@trungkhai/dynamic-form 0.1.4 → 0.1.6
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/dist/index.cjs.js +1 -1
- package/dist/index.d.ts +93 -5
- package/dist/index.es.js +1900 -1005
- package/package.json +1 -1
package/dist/index.cjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("react/jsx-runtime"),S=require("antd"),c=require("react"),te=require("dayjs"),Fe=require("@ant-design/icons"),se=c.createContext(null);function D(){const e=c.useContext(se);if(!e)throw new Error("useDynamicFormContext must be used within DynamicFormProvider");return e}function et(){return c.useContext(se)}function Ae(e,t=[]){for(const r of t){if(typeof r=="function")continue;const{match:i,render:a}=r;if(typeof i=="string"){if(i===e.field?.type?.code||i===e.code)return a}else if(i(e))return a}const n=e.field?.type?.code;for(const r of t);}function je(e,t=[],n={}){return Ae(e,t)??n[e.code]??n[e.field?.type?.code??""]}function ke(e,t){const n=t.option_config?.label_attr,r=t.option_config?.value_attr||"value";let i;if(n?.length){const a=n.join(" - ");e[a]!==void 0?i=String(e[a]):i=n.map(s=>e[s]).filter(s=>s!=null&&s!=="").join(" - ")}else i=String(e[r]??"");return{label:i,value:e[r]}}function Re(e,t){return t.option_config&&t.is_option_api?e?.map(n=>ke(n,t)):t.metas?.map(n=>({label:n.label,value:n.value}))}function Ee(e,t){const n=t.option_config?.value_attr||"value";return e[n]}function tt(e,t){const n=new Set,r=[];return e.forEach(i=>{const a=Ee(i,t),s=String(a);n.has(s)||(n.add(s),r.push(i))}),r}function ne(e,t){let n;return(...r)=>{n&&clearTimeout(n),n=setTimeout(()=>e(...r),t)}}const nt=({onSearchKeyword:e,searchDebounceMs:t=500,...n})=>{const[r,i]=c.useState(""),a=c.useMemo(()=>ne(o=>e?.(o),t),[e,t]),s=o=>{i(o),a(o)};return u.jsx(S.Select,{allowClear:!0,showSearch:!0,searchValue:r,onSearch:s,filterOption:!1,...n})},rt=c.memo(nt),it=({fieldName:e,formInstance:t,...n})=>{const r=S.Form.useWatch(e,t);c.useEffect(()=>{if(r?.fileList?.length&&r.fileList.some(s=>!s.type?.startsWith("image/"))){const s=r.fileList.filter(o=>o.type?.startsWith("image/"));t.setFieldValue(e,s?.length?{file:s[0]?.originFileObj,fileList:s}:null)}},[e,t,r]);const i=u.jsx("button",{style:{border:0,background:"none",cursor:"pointer"},type:"button",children:u.jsx(Fe.FileImageOutlined,{})});return u.jsx(S.Upload,{listType:"picture-card",accept:"image/*",...n,children:i})},at=c.memo(it),st=({fieldName:e,formInstance:t,...n})=>{const r=S.Form.useWatch(e,t);return u.jsx(S.Upload,{fileList:r?.fileList,...n,children:u.jsx(S.Button,{icon:u.jsx(Fe.UploadOutlined,{})})})},ot=c.memo(st),Ce=({formInstance:e,uploadUrl:t,setFieldState:n})=>{const{client:r,upload:i,i18n:a,renderers:s}=D(),{messages:o}=a,m=c.useCallback(()=>{if(i.upload)return i.upload;const l=t??i.uploadUrl;if(l)return async({file:h,signal:y,onProgress:f,fieldCode:_,fieldGroup:w,metadata:v})=>{const g=i.getPayload?i.getPayload({file:h,fieldCode:_,fieldGroup:w,uploadUrl:l,signal:y,onProgress:f,metadata:v}):(()=>{const x=new FormData;return x.append("file",h),v&&Object.entries(v).forEach(([R,k])=>{x.append(R,String(k))}),x})(),F=(await r.request({method:"POST",url:l,data:g,headers:g instanceof FormData?{"Content-Type":"multipart/form-data"}:void 0,signal:y,onUploadProgress:x=>{f?.(Math.round(x.loaded*100/(x.total||1)))}})).data;return{uid:h.uid,...F,path:String(F.path??"")}}},[r,i,t]),d=c.useCallback((l,h)=>y=>{const{file:f,onProgress:_,onError:w,onSuccess:v}=y,g=new AbortController,A=m();return A?(A({file:f,fieldCode:l,fieldGroup:h,uploadUrl:t??i.uploadUrl,signal:g.signal,onProgress:F=>_?.({percent:F})}).then(F=>v?.({...F,uid:F.uid??f.uid,path:F.path,upload_date:te().format("YYYY-MM-DD HH:mm:ss")})).catch(F=>w?.(F)),{abort:()=>g.abort()}):(w?.(new Error(o.uploadError??"Upload not configured")),{abort(){}})},[o.uploadError,m,i.uploadUrl,t]),b=c.useCallback((l,h)=>async y=>{const f=y.response?.path;return f?i.remove({path:f,fieldCode:l,fieldGroup:h}):!0},[i]),p=c.useCallback((l,{state:h,options:y,optionsLoading:f,optionsError:_,onSearchKeyword:w,readOnly:v=!1})=>{const{additional_config:g,field:A}=l,F=A?.type?.code,x=v||l.is_readonly||h?.disabled,R=je(l,s.fields);if(R)return R(l,{state:h,options:y,optionsLoading:f,optionsError:_,onSearchKeyword:w,readOnly:v,formInstance:e,disabled:!!x,setFieldState:n});const k=Re(y,l);switch(F){case"text":return g?.text?.textarea?u.jsx(S.Input.TextArea,{disabled:x,placeholder:o.inputPlaceholder(l.label),rows:g?.text?.rows}):u.jsx(S.Input,{disabled:x,placeholder:o.inputPlaceholder(l.label)});case"number":return u.jsx(S.InputNumber,{style:{width:"100%"},disabled:x,placeholder:o.inputPlaceholder(l.label),min:g?.number?.min,max:g?.number?.max});case"select":{const V={disabled:x,options:k,placeholder:o.selectPlaceholder(l.label),allowClear:!0,loading:f,mode:g?.select?.multiple?"multiple":void 0,notFoundContent:_?o.optionError:f?o.optionLoading:void 0};return w?u.jsx(rt,{...V,onSearchKeyword:w,searchDebounceMs:g?.select?.searchDebounceMs??500}):u.jsx(S.Select,{...V,showSearch:!0,optionFilterProp:"label"})}case"radio":return u.jsx(S.Radio.Group,{disabled:x,options:k});case"checkbox":return u.jsx(S.Checkbox.Group,{disabled:x,options:k});case"datetime":return u.jsx(S.DatePicker,{style:{width:"100%"},disabled:x,showTime:g?.datetime?.showTime,format:g?.datetime?.format});case"file":return u.jsx(ot,{disabled:x,fieldName:l.code,formInstance:e,multiple:g?.file?.multiple||!1,maxCount:g?.file?.max,accept:g?.file?.accept,customRequest:d(l.code,l),onRemove:b(l.code,l)});case"image":return u.jsx(at,{disabled:x,fieldName:l.code,formInstance:e,multiple:g?.image?.multiple||!1,maxCount:g?.image?.max,accept:g?.image?.accept??"image/*",customRequest:d(l.code,l),onRemove:b(l.code,l)});default:return null}},[d,b,e,o,s.fields,n]);return c.useMemo(()=>({getDynamicField:p}),[p])};function K(e){return JSON.stringify(e)}function Me(e,t){const n=e.get(t);if(n){if(Date.now()>n.expiresAt){e.delete(t);return}return n.data}}function De(e,t,n,r){e.set(t,{data:n,expiresAt:Date.now()+r})}async function $(e,t,n,r,i){const a=e[t];if(e.cache.enabled){const d=Me(a,n);if(d!==void 0)return d}const s=new AbortController,o=i?AbortSignal.any([i,s.signal]):s.signal,m=await r(o);return e.cache.enabled&&De(a,n,m,e.cache.ttlMs),m}function U(e,t){return t.split(".").reduce((n,r)=>{if(n&&typeof n=="object")return n[r]},e)}function lt(e,t){if(typeof e!="string")return e;const n=e.match(/^\{\{(.+?)\}\}$/);if(!n)return e;const r=n[1].trim(),i=U(t,r);return i!==void 0?i:e}function Ve(e,t){const n={};for(const r in e)n[r]=lt(e[r],t);return n}function ct(e,t){const n={...e};return t.forEach(r=>{const i=e[r.code];if(i==null)return;switch(r.field?.type?.code){case"datetime":{const s=te(i);s.isValid()&&(n[r.code]=s);break}case"file":case"image":{if(Array.isArray(i)&&i.length>0){const s=i.map((o,m)=>{const d=o;return{uid:String(d.uid??d.path??m),name:d.name??`file-${m}`,status:"done",percent:100,type:d.type,size:d.size,response:o}});n[r.code]={fileList:s}}break}}}),n}function Pe(e){const t=e.option_config?.api_options?.params||{},n=e.option_config?.api_options?.data||{},r=i=>Object.values(i).filter(a=>typeof a=="string"&&a.startsWith("{{")&&a.endsWith("}}")).map(a=>a.slice(2,-2).trim());return Array.from(new Set([...r(t),...r(n)]))}function L(e,t){const n={};for(const r in e){const i=e[r];if(typeof i=="string"&&i.startsWith("{{")&&i.endsWith("}}")){const a=i.slice(2,-2).trim();n[r]=t?.[a]}else n[r]=i}return n}function z(e,t){return e.replace(/\{\{\s*(\w+)\s*\}\}/g,(n,r)=>{const i=t?.[r];return i!=null?String(i):""})}function dt(e,t,n){const i=t.find(a=>a.code===e)?.additional_config?.on_field_change?.clear??[];return i.length===0?[]:i.filter(a=>n?.[a]!==void 0&&n?.[a]!==null)}function Te(e,t){const n=c.useMemo(()=>Pe(e),[e]),r=S.Form.useWatch(n.length>0?n:void 0,t);return c.useMemo(()=>{if(!n.length)return{};const i={};return n.forEach((a,s)=>{Array.isArray(r)?i[a]=r[s]:i[a]=r}),i},[n,r])}function Oe({group:e,formInstance:t,searchKeyword:n="",searchDebounceMs:r=500}){const i=D(),a=Te(e,t),s=S.Form.useWatch(e.code,t),[o,m]=c.useState(),[d,b]=c.useState(!1),[p,l]=c.useState(),h=c.useRef(null),[y,f]=c.useState(n),_=e.additional_config?.select?.search_keyword??!1,w=c.useMemo(()=>ne(A=>f(A),r),[r]);c.useEffect(()=>{_?w(n):f("")},[n,_,w]);const v=c.useMemo(()=>{const A=e.option_config?.api_options?.params,F=e.option_config?.api_options?.data;if(!(!A&&!F))return{params:A?L(A,a):void 0,data:F?L(F,a):void 0}},[a,e]),g=c.useCallback(async()=>{if(!e.option_config||!e.is_option_api||!e.option_config.url)return;h.current?.abort();const A=new AbortController;h.current=A;const F=e.option_config.method?.toUpperCase()==="GET"||!e.option_config.method,x=_?y:"",R=K([e.code,e.option_config.url,e.option_config.method,v,x]);b(!0),l(void 0);try{const k=await $(i,"optionCache",R,async E=>{const M=await i.client.request({method:e.option_config?.method||"GET",url:e.option_config?.url,params:F&&_?{...v?.params,keywords:x}:v?.params,data:!F&&_?{...v?.data,keywords:x}:v?.data,signal:E});return i.parsers.optionResponse(M.data,e)},A.signal),V=Array.isArray(s)?s:s==null?[]:[s],G=new Set(k.map(E=>String(Ee(E,e)))),P=V.filter(E=>E==null||E===""?!1:!G.has(String(E)));let I=[];P.length>0&&(I=(await Promise.all(P.map(async E=>{const M=K([e.code,e.option_config?.url,e.option_config?.method,v,"selected",E]);return $(i,"optionCache",M,async re=>{const T={[e.option_config?.value_attr||"value"]:E},N=await i.client.request({method:e.option_config?.method||"GET",url:e.option_config?.url,params:F?{...v?.params,filter:{...v?.params?.filter,...T}}:v?.params,data:F?v?.data:{...v?.data,filter:{...v?.data?.filter,...T}},signal:re});return i.parsers.optionResponse(N.data,e)},A.signal)}))).flat());const Y=tt([...k,...I],e);A.signal.aborted||m(Y)}catch(k){A.signal.aborted||l(k)}finally{A.signal.aborted||b(!1)}},[v,i,y,e,_,s]);return c.useEffect(()=>(e.option_config&&e.is_option_api&&g(),()=>h.current?.abort()),[g,e]),{options:o,isLoading:d,error:p,refetch:g}}const ut=({group:e,formInstance:t,fieldState:n,setFieldState:r,uploadUrl:i,readOnly:a=!1,size:s="middle",...o})=>{const{getDynamicField:m}=Ce({formInstance:t,uploadUrl:i,setFieldState:r}),d=S.Form.useWatch(e.code,t),[b,p]=c.useState(""),l=e.additional_config?.select?.search_keyword??!1,{options:h,isLoading:y,error:f}=Oe({group:e,formInstance:t,searchKeyword:b,searchDebounceMs:e.additional_config?.select?.searchDebounceMs??500}),_=c.useCallback(v=>{p(v)},[]);c.useEffect(()=>{e.additional_config?.on_field_empty?.disable?.length&&e.additional_config.on_field_empty.disable.forEach(v=>{r(v,{disabled:!d})})},[d,t,e,r]);const w=s==="small"?4:12;return u.jsx(S.Form.Item,{label:e.label,name:e.code,hidden:n?.hidden,rules:[{required:n?.required||!1}],style:{marginBottom:w,...o.style},...o,children:m(e,{state:n,options:h,optionsLoading:y,optionsError:f,onSearchKeyword:l?_:void 0,readOnly:a})})};function mt(e,t){return e.group.id===t.group.id&&e.readOnly===t.readOnly&&e.uploadUrl===t.uploadUrl&&e.size===t.size&&e.fieldState?.disabled===t.fieldState?.disabled&&e.fieldState?.hidden===t.fieldState?.hidden&&e.fieldState?.required===t.fieldState?.required}const Le=c.memo(ut,mt);function qe({fieldGroups:e,fieldStates:t,renderField:n,gutter:r,defaultColSpan:i}){return u.jsx(S.Row,{gutter:r,children:e.map(a=>{const s=t[a.code]?.hidden?0:Number(a.additional_config?.field_col_span)||i;return u.jsx(S.Col,{xs:s,children:n(a)},a.id)})})}function Ue(e){return c.useMemo(()=>{const t=e?.form?.field_groups??[],n=new Map,r={};t.forEach(a=>{n.set(a.code,a),a.additional_config?.default!==void 0&&(r[a.code]=a.additional_config.default)});const i=t.filter(a=>!a.is_hidden);return{fieldGroups:t,fieldByCode:n,visibleFieldGroups:i,initialValues:r}},[e])}function ge(e){const t={};return e.forEach(n=>{t[n.code]={disabled:n.is_readonly,hidden:n.is_hidden,required:n.is_required}}),t}function Ge(e){const[t,n]=c.useState(()=>ge(e));c.useEffect(()=>{n(ge(e))},[e]);const r=c.useCallback((i,a)=>{n(s=>({...s,[i]:{...s[i],...a}}))},[]);return{fieldStates:t,setFieldStates:n,setFieldState:r}}function Ie({formInstance:e,fieldByCode:t,relatedData:n,transformers:r}){return{buildProcessedValues:c.useCallback(async()=>{await e.validateFields();const a=e.getFieldsValue(),s={};for(const d of Object.keys(a)){const b=t.get(d);if(!b)continue;let p;switch(b.field?.type?.code){case"datetime":p=a[d]?te(a[d]).format(b.additional_config?.datetime?.format):null;break;case"image":case"file":a[d]?.fileList?.length&&(p=a[d].fileList.filter(l=>l.percent===100).map(l=>({...l.response,name:l.name,type:l.type,size:l.size})));break;default:p=a[d]}r.transformFieldValue&&(p=r.transformFieldValue(d,p,b)),s[d]=p}let o=s;return r.transformSubmitValues&&(o=r.transformSubmitValues(o,Array.from(t.values()),n)),(r.parseRelatedDataTemplates??Ve)(o,n??{})},[t,e,n,r])}}const Be=c.forwardRef(({formConfig:e,formInstance:t,relatedData:n,uploadUrl:r,uploadResourceUrl:i,submitTrackingUrl:a,onBeforeSubmit:s,onSubmitSuccess:o,onSubmitError:m,isRedirectAfterCreate:d,onRedirect:b,size:p="middle",manualSubmit:l=!1,onValuesChange:h,readOnly:y=!1,submitDebounceMs:f,gutter:_=[8,0],defaultColSpan:w=12,submitButtonLabel:v},g)=>{const{message:A}=S.App.useApp(),F=D(),{i18n:x,client:R,parsers:k,redirectHandler:V,renderers:G,transformers:P}=F,I=r??i,Y=f??F.submitDebounceMs,E=v??x.messages.submit,{fieldGroups:M,fieldByCode:re,initialValues:B}=Ue(e),{fieldStates:T,setFieldState:N}=Ge(M),{buildProcessedValues:J}=Ie({formInstance:t,fieldByCode:re,relatedData:n,transformers:P}),Q=c.useRef(!1),[he,ye]=c.useState(!1),[be,_e]=c.useState(!1);c.useEffect(()=>{if(Object.keys(B).length>0){const j=P.normalizeInitialValues?P.normalizeInitialValues(B,M):B;t.setFieldsValue(j)}},[M,t,B,P]);const X=c.useCallback(async()=>{if(!Q.current){Q.current=!0,ye(!0);try{let j=await J();try{a&&(_e(!0),await R.request({method:"POST",url:a,data:j}));const C=await s?.(j);if(C===!1)return;C&&typeof C=="object"&&(j=C)}catch(C){console.error(C);return}finally{_e(!1)}const O=await R.request({method:e.method,url:e.action,data:j});t.resetFields(M.filter(C=>!C.is_hidden).map(C=>C.code));const W=k.submitResponse(O.data);d&&W.redirectUrl&&(b??V)(W.redirectUrl,"_blank"),o?.({values:j,response:O.data,data:W.data??O.data})}catch(j){const O=j;A.error(O?.response?.data?.message??x.messages.submitError),m?.(j)}finally{Q.current=!1,ye(!1)}}},[J,R,M,e.action,e.method,t,x.messages.submitError,d,A,s,b,m,o,k,V,a]);c.useImperativeHandle(g,()=>({submit:X,getProcessedValues:J,isSubmitting:()=>Q.current}),[J,X]);const ve=c.useMemo(()=>ne(()=>{X()},Y),[X,Y]),Qe=c.useCallback((j,O)=>{Object.keys(j).forEach(W=>{const C=dt(W,M,t.getFieldsValue());C.length>0&&t.resetFields(C)}),h?.(j,O)},[M,t,h]),we=c.useCallback(j=>u.jsx(Le,{group:j,formInstance:t,fieldState:T[j.code],setFieldState:N,uploadUrl:I,readOnly:y,size:p},j.id),[T,t,y,I,N,p]),Xe=G.layout?G.layout({fieldGroups:M,fieldStates:T,renderField:we,gutter:_,defaultColSpan:w,size:p}):u.jsx(qe,{fieldGroups:M,fieldStates:T,renderField:we,gutter:_,defaultColSpan:w,size:p}),Ze=!l&&!y&&(G.submitActions?G.submitActions({onSubmit:ve,loading:he||be,label:E}):u.jsx(S.Flex,{justify:"flex-end",children:u.jsx(S.Button,{type:"primary",onClick:ve,loading:he||be,children:E})}));return u.jsxs(S.Form,{layout:"vertical",form:t,size:p,onValuesChange:Qe,children:[Xe,Ze]})});Be.displayName="DynamicForm";function oe(e){if(!e)return;const{mode:t}=e;if(t==="api"&&e.api?.url)return e.api;if(t==="api_ids"&&e.api_ids?.url){const n=e.api_ids,r=n.method?.toUpperCase()==="POST";return{url:n.url,method:n.method,data_path:n.data_path,mapping_attr:n.mapping_attr,link:n.link,result_type:n.result_type??"array",params:n.params??(!r&&!n.data?{ids:"{{value}}"}:void 0),data:n.data??(r&&!n.params?{ids:"{{value}}"}:void 0)}}if(t==="api_detail"&&e.api_detail?.url){const n=e.api_detail;return{url:n.url,method:n.method,data_path:n.data_path,mapping_attr:n.mapping_attr,link:n.link,result_type:n.result_type??"object",url_template:n.url_template??!0,params:n.params,data:n.data}}}function Se(e){return{value:e,id:e}}function We(e,t){const n=t.method||"GET",r=n.toUpperCase()==="GET";if(t.url_template)return(Array.isArray(e)?e.filter(m=>m!=null&&m!==""):e!=null&&e!==""?[e]:[]).map(m=>{const d=Se(m),b=z(t.url,d),p=t.params?L(t.params,d):void 0,l=t.data?L(t.data,d):void 0;return{method:n,url:b,params:r?p:void 0,data:r?void 0:l}});const i=Se(e),a=t.params?L(t.params,i):void 0,s=t.data?L(t.data,i):void 0;return[{method:n,url:t.url,params:r?a:void 0,data:r?void 0:s}]}function le(e,t){const n=t.data_path?U(e,t.data_path):e;return(t.result_type??(Array.isArray(n)?"array":"object"))==="array"?Array.isArray(n)?n:n!=null?[n]:[]:Array.isArray(n)?n.length?[n[0]]:[]:n&&typeof n=="object"?[n]:[]}function ce(e,t){return _t(e,t.mapping_attr)}function de(e,t){return vt(t.link,e)}async function Ke(e,t,n,r){const i=We(e,t);if(!i.length)return[];const a=await Promise.all(i.map(o=>n({...o,signal:r}))),s=[];for(const o of a)s.push(...le(o.data,t));return s}function q(e){return!!(e==null||e===""||Array.isArray(e)&&e.length===0)}function $e(e,t){const n=e.option_config?.api_options?.params,r=e.option_config?.api_options?.data;if(!n&&!r)return;const i=a=>{const s={};for(const o in a)if(typeof a[o]=="string"&&a[o].startsWith("{{")&&a[o].endsWith("}}")){const m=a[o].slice(2,-2).trim();s[o]=t?.[m]}else s[o]=a[o];return s};return{params:n?i(n):void 0,data:r?i(r):void 0}}function ft(e,t){const n=t.option_config?.label_attr,r=t.option_config?.value_attr||"";if(n?.length){const i=n.join(" - ");return e[i]!==void 0?String(e[i]):n.map(a=>e[a]).filter(a=>a!=null&&a!=="").join(" - ")}return String(e[r]??"")}function pt(e,t){if(!t?.length)return null;const r=(Array.isArray(e)?e:[e]).map(i=>t.find(a=>String(a.value)===String(i))?.label).filter(i=>!!i);return r.length?r.join(", "):null}function ht(e,t,n){if(q(e))return null;const r=t.option_config?.value_attr||"value",i=Array.isArray(e)?e:[e];if(t.is_option_api&&n?.length){const s=i.map(o=>{const m=n.find(d=>String(d[r])===String(o));return m?ft(m,t):String(o)}).filter(Boolean);return s.length?s.join(", "):null}const a=pt(e,t.metas);return a||i.map(String).join(", ")}function yt(e,t){if(q(e))return null;const n=t.additional_config?.datetime?.format,r=te(e);return r.isValid()?n?r.format(n):r.format("YYYY-MM-DD HH:mm:ss"):String(e)}function bt(e){if(q(e))return null;if(Array.isArray(e)){const t=e.map(n=>typeof n=="object"&&n&&"name"in n?String(n.name):String(n)).filter(Boolean);return t.length?t.join(", "):null}return String(e)}function _t(e,t){return t?.length?t.map(n=>{const r=U(e,n)??e[n];return r!=null?String(r):""}).filter(Boolean).join(" - "):JSON.stringify(e)}function vt(e,t){return e?e.replace(/\{\{(.+?)\}\}/g,(n,r)=>{const i=r.trim(),a=U(t,i)??t[i];return a!=null?String(a):""}):null}function ae(e,t,n){if(q(e))return null;switch(t?.mode??"formatted"){case"raw":case"formatted":return Array.isArray(e)?e.map(String).join(", "):String(e);case"api":case"api_ids":case"api_detail":{const i=oe(t);if(!n||!i)return Array.isArray(e)?e.map(String).join(", "):String(e);const a=le(n,i);return a.length?a.map(o=>{const m=ce(o,i),d=de(o,i);return d?`${m} (${d})`:m}).filter(Boolean).join(", ")||null:String(e)}default:return String(e)}}function ze(e,t,n){const r=e.additional_config?.view_value;if(r?.mode==="api"||r?.mode==="api_ids"||r?.mode==="api_detail")return ae(t,r,n.viewValueFetched);switch(e.field?.type?.code){case"text":case"number":return q(t)?null:String(t);case"datetime":return yt(t,e);case"select":case"radio":case"checkbox":return ht(t,e,n.optionList);case"image":case"file":return bt(t);default:return r?ae(t,r,n.viewValueFetched):q(t)?null:String(t)}}const ee=new Map,wt=3e4;function gt(e){const t=ee.get(e);if(t){if(Date.now()>t.expiresAt){ee.delete(e);return}return t.error}}function xe(e,t){ee.set(e,{error:t,expiresAt:Date.now()+wt})}function H(e,t,n=!0){const r=D(),[i,a]=c.useState(),[s,o]=c.useState(!1),[m,d]=c.useState(),b=c.useRef(t),p=c.useRef(r);b.current=t,p.current=r;const l=K(e);return c.useEffect(()=>{if(!n){a(void 0),d(void 0),o(!1);return}const y=gt(l);if(y!==void 0){d(y),o(!1);return}const f=new AbortController;return o(!0),d(void 0),(async()=>{try{const w=await $(p.current,"viewCache",l,v=>b.current(v),f.signal);f.signal.aborted||(a(w),d(void 0))}catch(w){f.signal.aborted||(xe(l,w),d(w))}finally{f.signal.aborted||o(!1)}})(),()=>f.abort()},[n,l]),{data:i,isLoading:s,error:m,refetch:async()=>{if(ee.delete(l),!n)return;const y=new AbortController;o(!0),d(void 0);try{const f=await $(p.current,"viewCache",l,_=>b.current(_),y.signal);return a(f),f}catch(f){throw xe(l,f),d(f),f}finally{o(!1)}}}}const St=({value:e,code:t,modeConfig:n})=>{const{client:r,renderers:i,i18n:a}=D(),s=c.useMemo(()=>(Array.isArray(e)?e:[e]).filter(Boolean),[e]),{data:o,isLoading:m,error:d}=H(["api_detail",t,s,n?.url,n?.method],async l=>(await Promise.all(s.map(async y=>{const f=z(n?.url||"",{id:y});return(await r.request({method:n?.method,url:f,signal:l})).data}))).filter(Boolean),!!(s.length&&n?.url)),b=(l,h,y)=>i.link?i.link({url:l,label:h,data:y}):u.jsx("a",{href:l,target:"_blank",rel:"noreferrer",children:h}),p=l=>{const h=n?.mapping_attr?.map(y=>l?.[y]).join(" - ");if(n?.link){const y=z(n.link,l);return b(y,h,l)}return h};return m?u.jsx(u.Fragment,{children:i.viewLoading?.()??u.jsx(S.Spin,{size:"small"})}):d?u.jsx(u.Fragment,{children:i.viewError?.(d)??a.messages.viewError}):o?.length?u.jsx(u.Fragment,{children:o.map((l,h)=>u.jsx("div",{children:p(l)},h))}):u.jsx(u.Fragment,{children:i.viewEmpty?.()??a.messages.viewEmpty})},ue=c.memo(St),xt=({value:e,code:t,modeConfig:n})=>{const{client:r,renderers:i,i18n:a}=D(),{data:s,isLoading:o,error:m}=H(["api_ids",t,e,n?.url,n?.method],async p=>{const l=n?.method||"GET",h=l.toUpperCase()==="POST",y=Array.isArray(e)?e:[e],_=(await r.request({method:l,url:n?.url||"",data:h?{ids:y}:void 0,params:h?void 0:{ids:y},signal:p})).data,w=n?.data_path?U(_,n.data_path):_;return Array.isArray(w)?w:_},!!(e&&n?.url)),d=(p,l,h)=>i.link?i.link({url:p,label:l,data:h}):u.jsx("a",{href:p,target:"_blank",rel:"noreferrer",children:l}),b=p=>{const l=n?.mapping_attr?.map(h=>p?.[h]).join(" - ");if(n?.link){const h=z(n.link,p);return d(h,l,p)}return l};return o?u.jsx(u.Fragment,{children:i.viewLoading?.()??u.jsx(S.Spin,{size:"small"})}):m?u.jsx(u.Fragment,{children:i.viewError?.(m)??a.messages.viewError}):s?Array.isArray(e)?u.jsx(S.Flex,{vertical:!0,children:(Array.isArray(s)?s:[s]).map((p,l)=>u.jsx("div",{children:b(p)},p.id??l))}):b(Array.isArray(s)?s[0]:s):u.jsx(u.Fragment,{children:i.viewEmpty?.()??a.messages.viewEmpty})},me=c.memo(xt),Ft=({value:e,code:t,modeConfig:n,viewConfig:r})=>{const{client:i,renderers:a,i18n:s}=D(),o=c.useMemo(()=>n??(r?oe(r):void 0),[n,r]),m=c.useMemo(()=>["api_view",t,e,o?.url,o?.method,o?.data_path],[t,e,o?.url,o?.method,o?.data_path]),d=c.useCallback(async f=>o?Ke(e,o,_=>i.request({..._,signal:f})):[],[i,o,e]),{data:b,isLoading:p,error:l}=H(m,d,!!(e&&o?.url)),h=(f,_,w)=>a.link?a.link({url:f,label:_,data:w}):u.jsx("a",{href:f,target:"_blank",rel:"noreferrer",children:_}),y=(f,_)=>{if(!o)return null;const w=ce(f,o),v=de(f,o),g=v?h(v,w,f):w;return u.jsx("div",{children:g},f.id??_)};return p?u.jsx(u.Fragment,{children:a.viewLoading?.()??u.jsx(S.Spin,{size:"small"})}):l?u.jsx(u.Fragment,{children:a.viewError?.(l)??s.messages.viewError}):b?.length?o?.result_type==="object"&&b.length===1?y(b[0],0):u.jsx(S.Flex,{vertical:!0,children:b.map(y)}):u.jsx(u.Fragment,{children:a.viewEmpty?.()??s.messages.viewEmpty})},fe=c.memo(Ft);function At(e){return!!(e.option_config&&e.is_option_api)}function jt(e,t){const n=D(),r=K(["viewModeOptions",e.map(a=>a.code),t]),{data:i}=H([r],async a=>{const s={};return await Promise.all(e.map(async o=>{if(!o.option_config?.url)return;const m=$e(o,t),d=o.option_config.method?.toUpperCase()==="GET"||!o.option_config.method,b=await n.client.request({method:o.option_config.method||"GET",url:o.option_config.url,params:d?m?.params:void 0,data:d?void 0:m?.data,signal:a});s[o.code]={optionList:n.parsers.optionResponse(b.data,o)}})),s},e.length>0);return i??{}}const kt=({formConfig:e,formValues:t})=>{const n=e?.form?.field_groups??[],r=c.useMemo(()=>n.filter(At),[n]),i=jt(r,t);return c.useMemo(()=>n.filter(s=>!s.is_hidden).map(s=>{const o=t?.[s.code],m=s.additional_config?.view_value,d=m?.mode;if(d==="api"&&m)return{key:s.code,label:s.label,rawValue:o,viewValue:u.jsx(fe,{code:s.code,value:o,viewConfig:m}),field_group:s};if(d==="api_ids"&&m?.api_ids)return{key:s.code,label:s.label,rawValue:o,viewValue:u.jsx(me,{code:s.code,value:o,modeConfig:m.api_ids}),field_group:s};if(d==="api_detail"&&m?.api_detail)return{key:s.code,label:s.label,rawValue:o,viewValue:u.jsx(ue,{code:s.code,value:o,modeConfig:m.api_detail}),field_group:s};const b=i[s.code]??{};return{key:s.code,label:s.label,rawValue:o,viewValue:ze(s,o,b),field_group:s}}),[i,n,t])},Rt=({code:e,value:t,fieldGroup:n})=>{const r=n?.additional_config?.view_value;switch(r?.mode){case"raw":return t;case"api":return u.jsx(fe,{code:e,value:t,viewConfig:r});case"api_ids":{const i=r?.api_ids;return u.jsx(me,{code:e,value:t,modeConfig:i})}case"api_detail":{const i=r?.api_detail;return u.jsx(ue,{code:e,value:t,modeConfig:i})}default:return t}},Et=c.memo(Rt),pe={submit:"Save",submitError:"Failed to submit form",inputPlaceholder:e=>`Enter ${e}`,selectPlaceholder:e=>`Select ${e}`,optionLoading:"Loading...",optionError:"Failed to load options",uploadError:"Upload failed",viewLoading:"Loading...",viewEmpty:"-",viewError:"Failed to load"},Ct={messages:pe},He=e=>{if(Array.isArray(e))return e;if(e&&typeof e=="object"&&"items"in e&&Array.isArray(e.items))return e.items;if(e&&typeof e=="object"&&"data"in e&&e.data&&typeof e.data=="object"&&"items"in(e.data??{})){const t=e.data;return Array.isArray(t.items)?t.items:[]}return[]},Ye=e=>({redirectUrl:e?.redirect_after_create,data:e}),Ne=(e,t)=>t?.dataPath?U(e,t.dataPath):e,Z={optionResponse:He,submitResponse:Ye,viewResponse:Ne},Je=(e,t="_blank")=>{window.open(e,t)},ie={upload:async()=>{throw new Error("Upload adapter is not configured")},remove:async()=>!1};function Mt({children:e,client:t,upload:n,i18n:r,parsers:i,renderers:a={},transformers:s={},cache:o,submitDebounceMs:m=200,redirectHandler:d,requestClient:b,uploadAdapter:p,deleteUploadAdapter:l,messages:h,optionResponseParser:y,customFieldRenderers:f}){const _=c.useRef(new Map),w=c.useRef(new Map),v=c.useMemo(()=>{const g=t??{request:b??(()=>{throw new Error("DynamicFormProvider requires client or requestClient")})},A=f?Object.entries(f).map(([R,k])=>({match:R,render:k})):[],F={...pe,...r?.messages,...h},x={...ie,...n,upload:n?.upload??p??ie.upload,remove:n?.remove??(l?R=>l(R.path):ie.remove)};return{client:g,upload:x,i18n:{messages:F},parsers:{optionResponse:i?.optionResponse??y??Z.optionResponse,submitResponse:i?.submitResponse??Z.submitResponse,viewResponse:i?.viewResponse??Z.viewResponse},renderers:{...a,fields:[...a.fields??[],...A]},transformers:s,cache:{enabled:o?.enabled??!0,ttlMs:o?.ttlMs??6e4},submitDebounceMs:m,redirectHandler:d??Je,optionCache:_.current,viewCache:w.current}},[t,b,n,p,l,r?.messages,h,i?.optionResponse,i?.submitResponse,i?.viewResponse,y,a,f,s,o?.enabled,o?.ttlMs,m,d]);return u.jsx(se.Provider,{value:v,children:e})}function Dt(e){return{request:async t=>({data:(await e({method:t.method,url:t.url,params:t.params,data:t.data,signal:t.signal,headers:t.headers,onUploadProgress:t.onUploadProgress})).data})}}exports.ApiDetailItem=ue;exports.ApiItem=me;exports.ApiViewItem=fe;exports.DefaultLayout=qe;exports.DynamicForm=Be;exports.DynamicFormProvider=Mt;exports.FormItem=Le;exports.MetaItemValue=Et;exports.buildApiViewRequests=We;exports.buildCacheKey=K;exports.cachedRequest=$;exports.createAxiosDynamicFormClient=Dt;exports.debounce=ne;exports.defaultI18n=Ct;exports.defaultMessages=pe;exports.defaultOptionResponseParser=He;exports.defaultParsers=Z;exports.defaultRedirectHandler=Je;exports.defaultSubmitResponseParser=Ye;exports.defaultViewResponseParser=Ne;exports.extractDependencyFields=Pe;exports.extractViewData=le;exports.fetchApiViewItems=Ke;exports.fillTemplate=z;exports.getByPath=U;exports.getCached=Me;exports.getMappedLabel=ce;exports.getMappedLink=de;exports.isEmptyValue=q;exports.mapOptionToSelectItem=ke;exports.mapOptions=Re;exports.normalizeApiViewConfig=oe;exports.normalizeMetaForForm=ct;exports.parseFormValues=Ve;exports.replaceTemplateInObject=L;exports.resolveApiOptionMeta=$e;exports.resolveFieldRenderer=Ae;exports.resolveFieldRendererFromMap=je;exports.resolveFieldViewValue=ze;exports.resolveViewValueConfig=ae;exports.setCache=De;exports.useCachedViewRequest=H;exports.useDependencyValues=Te;exports.useDynamicField=Ce;exports.useDynamicFormContext=D;exports.useDynamicFormContextOptional=et;exports.useDynamicOptions=Oe;exports.useFieldGroups=Ue;exports.useFieldStates=Ge;exports.useProcessedValues=Ie;exports.useViewMode=kt;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("react/jsx-runtime"),b=require("antd"),d=require("react"),ue=require("dayjs"),le=require("@ant-design/icons"),ge=d.createContext(null);function L(){const e=d.useContext(ge);if(!e)throw new Error("useDynamicFormContext must be used within DynamicFormProvider");return e}function wt(){return d.useContext(ge)}function Ne(e,t=[]){for(const r of t){if(typeof r=="function")continue;const{match:s,render:o}=r;if(typeof s=="string"){if(s===e.field?.type?.code||s===e.code)return o}else if(s(e))return o}const n=e.field?.type?.code;for(const r of t);}function Ue(e,t=[],n={}){return Ne(e,t)??n[e.code]??n[e.field?.type?.code??""]}function We(e,t){const n=t.option_config?.label_attr,r=t.option_config?.value_attr||"value";let s;if(n?.length){const o=n.join(" - ");e[o]!==void 0?s=String(e[o]):s=n.map(i=>e[i]).filter(i=>i!=null&&i!=="").join(" - ")}else s=String(e[r]??"");return{label:s,value:e[r]}}function $e(e,t){return t.option_config&&t.is_option_api?e?.map(n=>We(n,t)):t.metas?.map(n=>({label:n.label,value:n.value}))}function ze(e,t){const n=t.option_config?.value_attr||"value";return e[n]}function xt(e,t){const n=new Set,r=[];return e.forEach(s=>{const o=ze(s,t),i=String(o);n.has(i)||(n.add(i),r.push(s))}),r}function fe(e,t){let n;return(...r)=>{n&&clearTimeout(n),n=setTimeout(()=>e(...r),t)}}const vt=({onSearchKeyword:e,searchDebounceMs:t=500,...n})=>{const[r,s]=d.useState(""),o=d.useMemo(()=>fe(a=>e?.(a),t),[e,t]),i=a=>{s(a),o(a)};return c.jsx(b.Select,{allowClear:!0,showSearch:!0,searchValue:r,onSearch:i,filterOption:!1,...n})},jt=d.memo(vt),St=({fieldName:e,formInstance:t,...n})=>{const r=b.Form.useWatch(e,t);d.useEffect(()=>{if(r?.fileList?.length&&r.fileList.some(i=>!i.type?.startsWith("image/"))){const i=r.fileList.filter(a=>a.type?.startsWith("image/"));t.setFieldValue(e,i?.length?{file:i[0]?.originFileObj,fileList:i}:null)}},[e,t,r]);const s=c.jsx("button",{style:{border:0,background:"none",cursor:"pointer"},type:"button",children:c.jsx(le.FileImageOutlined,{})});return c.jsx(b.Upload,{listType:"picture-card",accept:"image/*",...n,children:s})},At=d.memo(St),Ft=({fieldName:e,formInstance:t,...n})=>{const r=b.Form.useWatch(e,t);return c.jsx(b.Upload,{fileList:r?.fileList,...n,children:c.jsx(b.Button,{icon:c.jsx(le.UploadOutlined,{})})})},kt=d.memo(Ft);function me(e,t,n={}){const{enabled:r=!0}=n,[s,o]=d.useState(),[i,a]=d.useState(!1),[p,m]=d.useState(),h=d.useRef(t);h.current=t;const f=d.useCallback(async()=>{if(r){a(!0);try{const l=await h.current();return o(l),m(void 0),l}catch(l){throw m(l),l}finally{a(!1)}}},[r]);return d.useEffect(()=>{r&&f()},[r,f,...e]),{data:s,isLoading:i,error:p,refetch:f}}function we(e){if(!e)return;const{mode:t}=e;if(t==="api"&&e.api?.url)return e.api;if(t==="api_ids"&&e.api_ids?.url){const n=e.api_ids,r=n.method?.toUpperCase()==="POST";return{url:n.url,method:n.method,data_path:n.data_path,mapping_attr:n.mapping_attr,link:n.link,result_type:n.result_type??"array",params:n.params??(!r&&!n.data?{ids:"{{value}}"}:void 0),data:n.data??(r&&!n.params?{ids:"{{value}}"}:void 0)}}if(t==="api_detail"&&e.api_detail?.url){const n=e.api_detail;return{url:n.url,method:n.method,data_path:n.data_path,mapping_attr:n.mapping_attr,link:n.link,result_type:n.result_type??"object",url_template:n.url_template??!0,params:n.params,data:n.data}}}function qe(e){return{value:e,id:e}}function He(e,t){const n=t.method||"GET",r=n.toUpperCase()==="GET";if(t.url_template)return(Array.isArray(e)?e.filter(p=>p!=null&&p!==""):e!=null&&e!==""?[e]:[]).map(p=>{const m=qe(p),h=oe(t.url,m),f=t.params?J(t.params,m):void 0,l=t.data?J(t.data,m):void 0;return{method:n,url:h,params:r?f:void 0,data:r?void 0:l}});const s=qe(e),o=t.params?J(t.params,s):void 0,i=t.data?J(t.data,s):void 0;return[{method:n,url:t.url,params:r?o:void 0,data:r?void 0:i}]}function xe(e,t){const n=t.data_path?X(e,t.data_path):e;return(t.result_type??(Array.isArray(n)?"array":"object"))==="array"?Array.isArray(n)?n:n!=null?[n]:[]:Array.isArray(n)?n.length?[n[0]]:[]:n&&typeof n=="object"?[n]:[]}function ve(e,t){return Et(e,t.mapping_attr)}function je(e,t){return Mt(t.link,e)}async function Ye(e,t,n,r){const s=He(e,t);if(!s.length)return[];const o=await Promise.all(s.map(a=>n({...a,signal:r}))),i=[];for(const a of o)i.push(...xe(a.data,t));return i}function q(e){return!!(e==null||e===""||Array.isArray(e)&&e.length===0)}function pe(e,t){const n=e.option_config?.api_options?.params,r=e.option_config?.api_options?.data;if(!n&&!r)return;const s=o=>{const i={};for(const a in o)if(typeof o[a]=="string"&&o[a].startsWith("{{")&&o[a].endsWith("}}")){const p=o[a].slice(2,-2).trim();i[a]=t?.[p]}else i[a]=o[a];return i};return{params:n?s(n):void 0,data:r?s(r):void 0}}function Ct(e,t){const n=t.option_config?.label_attr,r=t.option_config?.value_attr||"";if(n?.length){const s=n.join(" - ");return e[s]!==void 0?String(e[s]):n.map(o=>e[o]).filter(o=>o!=null&&o!=="").join(" - ")}return String(e[r]??"")}function Se(e,t){if(!t?.length)return null;const r=(Array.isArray(e)?e:[e]).map(s=>t.find(o=>String(o.value)===String(s))?.label).filter(s=>!!s);return r.length?r.join(", "):null}function ee(e,t,n){if(q(e))return null;const r=t.option_config?.value_attr||"value",s=Array.isArray(e)?e:[e];if(t.is_option_api&&n?.length){const i=s.map(a=>{const p=n.find(m=>String(m[r])===String(a));return p?Ct(p,t):String(a)}).filter(Boolean);return i.length?i.join(", "):null}const o=Se(e,t.metas);return o||s.map(String).join(", ")}function Je(e,t){if(q(e))return null;const n=t.additional_config?.datetime?.format,r=ue(e);return r.isValid()?n?r.format(n):r.format("YYYY-MM-DD HH:mm:ss"):String(e)}function Rt(e){if(q(e))return null;if(Array.isArray(e)){const t=e.map(n=>typeof n=="object"&&n&&"name"in n?String(n.name):String(n)).filter(Boolean);return t.length?t.join(", "):null}return String(e)}function Et(e,t){return t?.length?t.map(n=>{const r=X(e,n)??e[n];return r!=null?String(r):""}).filter(Boolean).join(" - "):JSON.stringify(e)}function Mt(e,t){return e?e.replace(/\{\{(.+?)\}\}/g,(n,r)=>{const s=r.trim(),o=X(t,s)??t[s];return o!=null?String(o):""}):null}function be(e,t,n){if(q(e))return null;switch(t?.mode??"formatted"){case"raw":case"formatted":return Array.isArray(e)?e.map(String).join(", "):String(e);case"api":case"api_ids":case"api_detail":{const s=we(t);if(!n||!s)return Array.isArray(e)?e.map(String).join(", "):String(e);const o=xe(n,s);return o.length?o.map(a=>{const p=ve(a,s),m=je(a,s);return m?`${p} (${m})`:p}).filter(Boolean).join(", ")||null:String(e)}default:return String(e)}}function Xe(e,t,n){const r=e.additional_config?.view_value;if(r?.mode==="api"||r?.mode==="api_ids"||r?.mode==="api_detail")return be(t,r,n.viewValueFetched);switch(e.field?.type?.code){case"text":case"number":return q(t)?null:String(t);case"datetime":return Je(t,e);case"select":case"radio":case"checkbox":return ee(t,e,n.optionList);case"image":case"file":return Rt(t);default:return r?be(t,r,n.viewValueFetched):q(t)?null:String(t)}}function te(e){const t=e.additional_config?.default;return typeof t=="string"&&t.trim()?t:void 0}function Ae(e,t,n){if(!t||typeof t!="object"||Array.isArray(t))return{};const r=n??te(e),s=t;if(r&&r in s){const o=s[r];if(o&&typeof o=="object"&&!Array.isArray(o))return o}return s}function Fe(e,t,n){if(Array.isArray(t))return t;const r=n??te(e);if(!r||q(t))return[];if(t&&typeof t=="object"&&!Array.isArray(t)){const s=t;if(r in s&&Array.isArray(s[r]))return s[r]}return ke(e,{[e.code]:t},r)}function Vt(e){return{id:e.id,code:e.code,form_id:e.id,method:"POST",action:"",config:{body:""},created_at:e.created_at??"",updated_at:e.updated_at??"",created_by:e.created_by,deleted_at:e.deleted_at,form:e}}function ye(e){return e.additional_config?.form?.submit_container_key??e.additional_config?.multiple_form?.submit_container_key??e.code}function Qe(e,t,n,r){const s=ye(e),o=t[e.code]??t[s];if(!q(o)&&o&&typeof o=="object"&&!Array.isArray(o)){const i=o;if(n in i){const a=i[n];return a&&typeof a=="object"&&!Array.isArray(a)?a:void 0}return i}}function ke(e,t,n){const r=ye(e),s=t[e.code]??t[r];if(q(s))return[];if(s&&typeof s=="object"&&!Array.isArray(s)){const o=s;if(n in o&&Array.isArray(o[n]))return o[n]}return Array.isArray(s)?s:[]}function X(e,t){return t.split(".").reduce((n,r)=>{if(n&&typeof n=="object")return n[r]},e)}function Tt(e,t){if(typeof e!="string")return e;const n=e.match(/^\{\{(.+?)\}\}$/);if(!n)return e;const r=n[1].trim(),s=X(t,r);return s!==void 0?s:e}function Ze(e,t){const n={};for(const r in e)n[r]=Tt(e[r],t);return n}function Ce(e,t){const n={...e};return t.forEach(r=>{const s=e[r.code];if(s==null)return;switch(r.field?.type?.code){case"datetime":{if(s&&typeof s=="object"&&typeof s.isValid=="function"){n[r.code]=s;break}const i=ue(s);i.isValid()&&(n[r.code]=i);break}case"file":case"image":{if(Array.isArray(s)&&s.length>0){const i=s.map((a,p)=>{const m=a;return{uid:String(m.uid??m.path??p),name:m.name??`file-${p}`,status:"done",percent:100,type:m.type,size:m.size,response:a}});n[r.code]={fileList:i}}break}case"form":{const i=te(r);n[r.code]=Ae(r,s,i);break}case"multiple-form":{const i=te(r);n[r.code]=Fe(r,s,i);break}}}),n}function Ge(e){const t=e.option_config?.api_options?.params||{},n=e.option_config?.api_options?.data||{},r=s=>Object.values(s).filter(o=>typeof o=="string"&&o.startsWith("{{")&&o.endsWith("}}")).map(o=>o.slice(2,-2).trim());return Array.from(new Set([...r(t),...r(n)]))}function J(e,t){const n={};for(const r in e){const s=e[r];if(typeof s=="string"&&s.startsWith("{{")&&s.endsWith("}}")){const o=s.slice(2,-2).trim();n[r]=t?.[o]}else n[r]=s}return n}function oe(e,t){return e.replace(/\{\{\s*(\w+)\s*\}\}/g,(n,r)=>{const s=t?.[r];return s!=null?String(s):""})}function Dt(e,t,n){const s=t.find(o=>o.code===e)?.additional_config?.on_field_change?.clear??[];return s.length===0?[]:s.filter(o=>n?.[o]!==void 0&&n?.[o]!==null)}const Pt=e=>({id:e.id,code:e.code,form_id:e.id,method:"POST",action:"",config:{body:""},created_at:e.created_at??"",updated_at:e.updated_at??"",created_by:e.created_by,deleted_at:e.deleted_at,form:e}),et=({group:e,value:t,onChange:n,disabled:r=!1,readOnly:s=!1,registerNestedForm:o})=>{const i=L(),[a]=b.Form.useForm(),p=d.useRef(null),m=e.additional_config?.form?.config_url,h=e.additional_config?.form?.method??"GET",{data:f,isLoading:l,error:u}=me([m,h],async()=>{if(!m)throw new Error("Missing additional_config.form.config_url");const _=await i.client.request({method:h,url:m});return i.parsers.formConfigResponse(_.data)},{enabled:!!m}),y=d.useMemo(()=>f?Pt(f):void 0,[f]);return d.useEffect(()=>{if(f)return o?.(e.code,p,{formCode:f.code,fieldType:"form"}),()=>{o?.(e.code,null)}},[e.code,f,o]),d.useEffect(()=>{if(!f)return;const _=Ae(e,t,f.code);a.setFieldsValue(Ce(_,f.field_groups))},[e,a,f,t]),m?l?c.jsx(b.Alert,{type:"info",message:"Loading...",showIcon:!0}):u||!y?c.jsx(b.Alert,{type:"error",message:"Failed to load nested form",showIcon:!0}):c.jsx("div",{style:{border:"1px solid rgba(5, 5, 5, 0.12)",borderRadius:8,padding:12,background:"#fff"},children:c.jsx(he,{ref:p,formConfig:y,formInstance:a,manualSubmit:!0,disableHtmlFormWrapper:!0,readOnly:r||s,onValuesChange:(_,g)=>{n?.(g??{})}})}):c.jsx(b.Alert,{type:"warning",message:"Missing nested form config_url",showIcon:!0})};function ne(e){return JSON.stringify(e)}function tt(e,t){const n=e.get(t);if(n){if(Date.now()>n.expiresAt){e.delete(t);return}return n.data}}function nt(e,t,n,r){e.set(t,{data:n,expiresAt:Date.now()+r})}async function re(e,t,n,r,s){const o=e[t];if(e.cache.enabled){const m=tt(o,n);if(m!==void 0)return m}const i=new AbortController,a=s?AbortSignal.any([s,i.signal]):i.signal,p=await r(a);return e.cache.enabled&&nt(o,n,p,e.cache.ttlMs),p}function Lt(e){const t=e?.field?.type?.code;return t==="select"||t==="radio"||t==="checkbox"}async function Ot(e,t,n,r,s){if(q(n))return s;if(!Lt(t))return String(n);const o=Se(n,t.metas);if(o)return o;if(t.is_option_api&&t.option_config?.url){const i=pe(t,r),a=t.option_config.method?.toUpperCase()==="GET"||!t.option_config.method,m={[t.option_config.value_attr||"value"]:n},h=ne(["collapseTitle",t.code,t.option_config.url,t.option_config.method,i,n]);try{const f=await re(e,"optionCache",h,async u=>{const y=await e.client.request({method:t.option_config?.method||"GET",url:t.option_config?.url,params:a?{...i?.params,filter:{...i?.params?.filter,...m}}:i?.params,data:a?i?.data:{...i?.data,filter:{...i?.data?.filter,...m}},signal:u});return e.parsers.optionResponse(y.data,t)}),l=ee(n,t,f);if(l)return l}catch{}}return ee(n,t)??s}function It(e,t,n,r,s){const o=L(),[i,a]=d.useState({});return d.useEffect(()=>{if(!t||!e){a({});return}let p=!1;return(async()=>{const h=await Promise.all(n.map(async(f,l)=>{const u=r[f.key]??{},y=await Ot(o,e,u[t],u,`${s} ${l+1}`);return[f.key,y]}));p||a(Object.fromEntries(h))})(),()=>{p=!0}},[o,s,n,t,e,r]),i}const qt=e=>({id:e.id,code:e.code,form_id:e.id,method:"POST",action:"",config:{body:""},created_at:e.created_at??"",updated_at:e.updated_at??"",created_by:e.created_by,deleted_at:e.deleted_at,form:e});function Bt({itemKey:e,nestedFormConfig:t,value:n,disabled:r=!1,readOnly:s=!1,registerItemRef:o,onValuesChange:i}){const[a]=b.Form.useForm(),p=d.useRef(null);return d.useEffect(()=>(o(e,p),()=>{o(e,null)}),[e,o]),d.useEffect(()=>{a.setFieldsValue(Ce(n??{},t.form.field_groups))},[a,t.form.field_groups,n]),c.jsx(he,{ref:p,formConfig:t,formInstance:a,manualSubmit:!0,disableHtmlFormWrapper:!0,readOnly:r||s,onValuesChange:(m,h)=>{i(e,h??{})}})}const rt=({group:e,value:t,onChange:n,disabled:r=!1,readOnly:s=!1,registerNestedForm:o})=>{const i=L(),a=e.additional_config?.multiple_form,p=a?.config_url,m=a?.method??"GET",h=a?.primary_field,f=d.useRef(0),[l,u]=d.useState([{key:f.current++}]),[y,_]=d.useState({}),g=d.useRef(y),S=d.useRef(l),[x,A]=d.useState(String(l[0]?.key??"")),w=d.useRef(new Map),{data:v,isLoading:M,error:k}=me([p,m],async()=>{if(!p)throw new Error("Missing additional_config.multiple_form.config_url");const j=await i.client.request({method:m,url:p});return i.parsers.formConfigResponse(j.data)},{enabled:!!p});d.useEffect(()=>{g.current=y},[y]),d.useEffect(()=>{S.current=l},[l]),d.useEffect(()=>{if(t===void 0)return;const j=v?.code??te(e),F=Fe(e,t,j);u(C=>{if(C.length===F.length&&C.length>0){const $=C.reduce((Y,G,ae)=>(Y[G.key]=F[ae]??{},Y),{});return _($),C}const V=F.length>0?F:[{}],P=V.map(()=>({key:f.current++})),Z=P.reduce(($,Y,G)=>($[Y.key]=V[G]??{},$),{});return _(Z),A(String(P[0]?.key??"")),P})},[e,v?.code,t]);const E=d.useMemo(()=>v?qt(v):void 0,[v]),K=d.useMemo(()=>v?.field_groups.find(j=>j.code===h),[v,h]),N=It(K,h,l,y,e.label),O=d.useCallback((j,F)=>{const C=j.map(V=>F[V.key]??{});n?.(C)},[n]),U=d.useCallback((j,F)=>{if(F){w.current.set(j,F);return}w.current.delete(j)},[]),H=d.useCallback((j,F)=>{_(C=>{const V={...C,[j]:F};return O(S.current,V),V})},[O]),T=d.useRef({submit:async()=>{},isSubmitting:()=>!1,getProcessedValues:async()=>({})});d.useEffect(()=>{T.current&&(T.current.getProcessedValues=async()=>await Promise.all(S.current.map(async F=>{const C=w.current.get(F.key);return C?.current?C.current.getProcessedValues():g.current[F.key]??{}})))},[]),d.useEffect(()=>{if(v)return o?.(e.code,T,{formCode:v.code,fieldType:"multiple-form"}),()=>{o?.(e.code,null)}},[e.code,v,o]);const z=d.useCallback(()=>{const j={key:f.current++};u(F=>{const C=[...F,j];return _(V=>{const P={...V,[j.key]:{}};return O(C,P),P}),C}),A(String(j.key))},[O]),I=d.useCallback(j=>{u(F=>{const C=F.filter(V=>V.key!==j);return _(V=>{const P={...V};return delete P[j],O(C,P),P}),A(String(C[0]?.key??"")),C})},[O]),Q=d.useMemo(()=>l.map((j,F)=>{const C=y[j.key]??{},V=N[j.key]??`${e.label} ${F+1}`;return{key:String(j.key),label:c.jsxs("div",{style:{display:"flex",justifyContent:"space-between",width:"100%"},children:[c.jsx("span",{children:V}),!r&&!s?c.jsx(le.DeleteOutlined,{onClick:P=>{P.preventDefault(),P.stopPropagation(),I(j.key)}}):null]}),children:E?c.jsx(Bt,{itemKey:j.key,nestedFormConfig:E,value:C,disabled:r,readOnly:s,registerItemRef:U,onValuesChange:H}):null}}),[r,e.label,I,l,E,H,s,U,N,y]);return p?h?M?c.jsx(b.Alert,{type:"info",message:"Loading...",showIcon:!0}):k||!E?c.jsx(b.Alert,{type:"error",message:"Failed to load nested form",showIcon:!0}):c.jsxs("div",{children:[c.jsx(b.Collapse,{accordion:!0,activeKey:x,onChange:j=>A(Array.isArray(j)?String(j[0]??""):String(j)),items:Q}),!r&&!s?c.jsx(b.Button,{style:{marginTop:12},block:!0,type:"dashed",onClick:z,icon:c.jsx(le.PlusOutlined,{}),children:"Add item"}):null]}):c.jsx(b.Alert,{type:"warning",message:"Missing multiple_form primary_field",showIcon:!0}):c.jsx(b.Alert,{type:"warning",message:"Missing multiple_form config_url",showIcon:!0})},st=({formInstance:e,uploadUrl:t,setFieldState:n})=>{const{client:r,upload:s,i18n:o,renderers:i}=L(),{messages:a}=o,p=d.useCallback(()=>{if(s.upload)return s.upload;const l=t??s.uploadUrl;if(l)return async({file:u,signal:y,onProgress:_,fieldCode:g,fieldGroup:S,metadata:x})=>{const A=s.getPayload?s.getPayload({file:u,fieldCode:g,fieldGroup:S,uploadUrl:l,signal:y,onProgress:_,metadata:x}):(()=>{const M=new FormData;return M.append("file",u),x&&Object.entries(x).forEach(([k,E])=>{M.append(k,String(E))}),M})(),v=(await r.request({method:"POST",url:l,data:A,headers:A instanceof FormData?{"Content-Type":"multipart/form-data"}:void 0,signal:y,onUploadProgress:M=>{_?.(Math.round(M.loaded*100/(M.total||1)))}})).data;return{uid:u.uid,...v,path:String(v.path??"")}}},[r,s,t]),m=d.useCallback((l,u)=>y=>{const{file:_,onProgress:g,onError:S,onSuccess:x}=y,A=new AbortController,w=p();return w?(w({file:_,fieldCode:l,fieldGroup:u,uploadUrl:t??s.uploadUrl,signal:A.signal,onProgress:v=>g?.({percent:v})}).then(v=>x?.({...v,uid:v.uid??_.uid,path:v.path,upload_date:ue().format("YYYY-MM-DD HH:mm:ss")})).catch(v=>S?.(v)),{abort:()=>A.abort()}):(S?.(new Error(a.uploadError??"Upload not configured")),{abort(){}})},[a.uploadError,p,s.uploadUrl,t]),h=d.useCallback((l,u)=>async y=>{const _=y.response?.path;return _?s.remove({path:_,fieldCode:l,fieldGroup:u}):!0},[s]),f=d.useCallback((l,{state:u,options:y,optionsLoading:_,optionsError:g,onSearchKeyword:S,readOnly:x=!1,registerNestedForm:A})=>{const{additional_config:w,field:v}=l,M=v?.type?.code,k=x||l.is_readonly||u?.disabled,E=Ue(l,i.fields);if(E)return E(l,{state:u,options:y,optionsLoading:_,optionsError:g,onSearchKeyword:S,readOnly:x,formInstance:e,disabled:!!k,setFieldState:n});const K=$e(y,l);switch(M){case"text":return w?.text?.textarea?c.jsx(b.Input.TextArea,{disabled:k,placeholder:a.inputPlaceholder(l.label),rows:w?.text?.rows}):c.jsx(b.Input,{disabled:k,placeholder:a.inputPlaceholder(l.label)});case"number":return c.jsx(b.InputNumber,{style:{width:"100%"},disabled:k,placeholder:a.inputPlaceholder(l.label),min:w?.number?.min,max:w?.number?.max});case"select":{const N={disabled:k,options:K,placeholder:a.selectPlaceholder(l.label),allowClear:!0,loading:_,mode:w?.select?.multiple?"multiple":void 0,notFoundContent:g?a.optionError:_?a.optionLoading:void 0};return S?c.jsx(jt,{...N,onSearchKeyword:S,searchDebounceMs:w?.select?.searchDebounceMs??500}):c.jsx(b.Select,{...N,showSearch:!0,optionFilterProp:"label"})}case"radio":return c.jsx(b.Radio.Group,{disabled:k,options:K});case"checkbox":return c.jsx(b.Checkbox.Group,{disabled:k,options:K});case"datetime":return c.jsx(b.DatePicker,{style:{width:"100%"},disabled:k,showTime:w?.datetime?.showTime,format:w?.datetime?.format});case"file":return c.jsx(kt,{disabled:k,fieldName:l.code,formInstance:e,multiple:w?.file?.multiple||!1,maxCount:w?.file?.max,accept:w?.file?.accept,customRequest:m(l.code,l),onRemove:h(l.code,l)});case"image":return c.jsx(At,{disabled:k,fieldName:l.code,formInstance:e,multiple:w?.image?.multiple||!1,maxCount:w?.image?.max,accept:w?.image?.accept??"image/*",customRequest:m(l.code,l),onRemove:h(l.code,l)});case"form":return c.jsx(et,{group:l,disabled:!!k,readOnly:x,registerNestedForm:A});case"multiple-form":return c.jsx(rt,{group:l,disabled:!!k,readOnly:x,registerNestedForm:A});default:return null}},[m,h,e,a,i.fields,n]);return d.useMemo(()=>({getDynamicField:f}),[f])};function it(e,t){const n=d.useMemo(()=>Ge(e),[e]),r=b.Form.useWatch(n.length>0?n:void 0,t);return d.useMemo(()=>{if(!n.length)return{};const s={};return n.forEach((o,i)=>{Array.isArray(r)?s[o]=r[i]:s[o]=r}),s},[n,r])}function ot({group:e,formInstance:t,searchKeyword:n="",searchDebounceMs:r=500}){const s=L(),o=it(e,t),i=b.Form.useWatch(e.code,t),[a,p]=d.useState(),[m,h]=d.useState(!1),[f,l]=d.useState(),u=d.useRef(null),[y,_]=d.useState(n),g=e.additional_config?.select?.search_keyword??!1,S=d.useMemo(()=>fe(w=>_(w),r),[r]);d.useEffect(()=>{g?S(n):_("")},[n,g,S]);const x=d.useMemo(()=>{const w=e.option_config?.api_options?.params,v=e.option_config?.api_options?.data;if(!(!w&&!v))return{params:w?J(w,o):void 0,data:v?J(v,o):void 0}},[o,e]),A=d.useCallback(async()=>{if(!e.option_config||!e.is_option_api||!e.option_config.url)return;u.current?.abort();const w=new AbortController;u.current=w;const v=e.option_config.method?.toUpperCase()==="GET"||!e.option_config.method,M=g?y:"",k=ne([e.code,e.option_config.url,e.option_config.method,x,M]);h(!0),l(void 0);try{const E=await re(s,"optionCache",k,async T=>{const z=await s.client.request({method:e.option_config?.method||"GET",url:e.option_config?.url,params:v&&g?{...x?.params,keywords:M}:x?.params,data:!v&&g?{...x?.data,keywords:M}:x?.data,signal:T});return s.parsers.optionResponse(z.data,e)},w.signal),K=Array.isArray(i)?i:i==null?[]:[i],N=new Set(E.map(T=>String(ze(T,e)))),O=K.filter(T=>T==null||T===""?!1:!N.has(String(T)));let U=[];O.length>0&&(U=(await Promise.all(O.map(async T=>{const z=ne([e.code,e.option_config?.url,e.option_config?.method,x,"selected",T]);return re(s,"optionCache",z,async I=>{const j={[e.option_config?.value_attr||"value"]:T},F=await s.client.request({method:e.option_config?.method||"GET",url:e.option_config?.url,params:v?{...x?.params,filter:{...x?.params?.filter,...j}}:x?.params,data:v?x?.data:{...x?.data,filter:{...x?.data?.filter,...j}},signal:I});return s.parsers.optionResponse(F.data,e)},w.signal)}))).flat());const H=xt([...E,...U],e);w.signal.aborted||p(H)}catch(E){w.signal.aborted||l(E)}finally{w.signal.aborted||h(!1)}},[x,s,y,e,g,i]);return d.useEffect(()=>(e.option_config&&e.is_option_api&&A(),()=>u.current?.abort()),[A,e]),{options:a,isLoading:m,error:f,refetch:A}}const Kt=({group:e,formInstance:t,fieldState:n,setFieldState:r,uploadUrl:s,readOnly:o=!1,size:i="middle",registerNestedForm:a,...p})=>{const{getDynamicField:m}=st({formInstance:t,uploadUrl:s,setFieldState:r}),h=b.Form.useWatch(e.code,t),[f,l]=d.useState(""),u=e.additional_config?.select?.search_keyword??!1,{options:y,isLoading:_,error:g}=ot({group:e,formInstance:t,searchKeyword:f,searchDebounceMs:e.additional_config?.select?.searchDebounceMs??500}),S=d.useCallback(A=>{l(A)},[]);d.useEffect(()=>{e.additional_config?.on_field_empty?.disable?.length&&e.additional_config.on_field_empty.disable.forEach(A=>{r(A,{disabled:!h})})},[h,t,e,r]);const x=i==="small"?4:12;return c.jsx(b.Form.Item,{label:e.label,name:e.code,hidden:n?.hidden,rules:[{required:n?.required||!1}],style:{marginBottom:x,...p.style},...p,children:m(e,{state:n,options:y,optionsLoading:_,optionsError:g,onSearchKeyword:u?S:void 0,readOnly:o,registerNestedForm:a})})};function Nt(e,t){return e.group.id===t.group.id&&e.readOnly===t.readOnly&&e.uploadUrl===t.uploadUrl&&e.size===t.size&&e.registerNestedForm===t.registerNestedForm&&e.fieldState?.disabled===t.fieldState?.disabled&&e.fieldState?.hidden===t.fieldState?.hidden&&e.fieldState?.required===t.fieldState?.required}const at=d.memo(Kt,Nt);function ct({fieldGroups:e,fieldStates:t,renderField:n,gutter:r,defaultColSpan:s}){return c.jsx(b.Row,{gutter:r,children:e.map(o=>{const i=t[o.code]?.hidden?0:Number(o.additional_config?.field_col_span)||s;return c.jsx(b.Col,{xs:i,children:n(o)},o.id)})})}function lt(e){return d.useMemo(()=>{const t=e?.form?.field_groups??[],n=new Map,r={};t.forEach(o=>{n.set(o.code,o);const i=o.field?.type?.code;o.additional_config?.default!==void 0&&i!=="form"&&i!=="multiple-form"&&(r[o.code]=o.additional_config.default)});const s=t.filter(o=>!o.is_hidden);return{fieldGroups:t,fieldByCode:n,visibleFieldGroups:s,initialValues:r}},[e])}function Be(e){const t={};return e.forEach(n=>{t[n.code]={disabled:n.is_readonly,hidden:n.is_hidden,required:n.is_required}}),t}function dt(e){const[t,n]=d.useState(()=>Be(e));d.useEffect(()=>{n(Be(e))},[e]);const r=d.useCallback((s,o)=>{n(i=>({...i,[s]:{...i[s],...o}}))},[]);return{fieldStates:t,setFieldStates:n,setFieldState:r}}function Ut(e){const t={},n={};return e.forEach(r=>{t[r.containerKey]||(t[r.containerKey]={}),t[r.containerKey][r.formCode]=r.value,n[r.fieldGroupCode]=[{form_code:r.formCode}]}),{containers:t,formReferences:n}}function ut({formInstance:e,fieldByCode:t,relatedData:n,transformers:r,nestedFormRefs:s}){return{buildProcessedValues:d.useCallback(async()=>{await e.validateFields();const i=e.getFieldsValue(),a={},p=[];for(const f of Object.keys(i)){const l=t.get(f);if(!l)continue;let u;switch(l.field?.type?.code){case"datetime":u=i[f]?ue(i[f]).format(l.additional_config?.datetime?.format):null;break;case"image":case"file":i[f]?.fileList?.length&&(u=i[f].fileList.filter(y=>y.percent===100).map(y=>({...y.response,name:y.name,type:y.type,size:y.size})));break;case"form":case"multiple-form":{const y=s.current.get(f);y?.ref.current?u=await y.ref.current.getProcessedValues():u=i[f],r.transformFieldValue&&(u=r.transformFieldValue(f,u,l)),y?p.push({fieldGroupCode:f,formCode:y.formCode,value:u,containerKey:ye(l)}):a[f]=u;break}default:u=i[f]}l.field?.type?.code!=="form"&&l.field?.type?.code!=="multiple-form"&&(r.transformFieldValue&&(u=r.transformFieldValue(f,u,l)),a[f]=u)}if(p.length>0){const{containers:f,formReferences:l}=Ut(p);Object.assign(a,f),Object.keys(l).length>0&&(a.form_references=l)}let m=a;return r.transformSubmitValues&&(m=r.transformSubmitValues(m,Array.from(t.values()),n)),(r.parseRelatedDataTemplates??Ze)(m,n??{})},[t,e,s,n,r])}}const he=d.forwardRef(({formConfig:e,formInstance:t,relatedData:n,uploadUrl:r,uploadResourceUrl:s,submitTrackingUrl:o,onBeforeSubmit:i,onSubmitSuccess:a,onSubmitError:p,isRedirectAfterCreate:m,onRedirect:h,size:f="middle",manualSubmit:l=!1,onValuesChange:u,readOnly:y=!1,submitDebounceMs:_,gutter:g=[8,0],defaultColSpan:S=12,submitButtonLabel:x,disableHtmlFormWrapper:A=!1},w)=>{const{message:v}=b.App.useApp(),M=L(),{i18n:k,client:E,parsers:K,redirectHandler:N,renderers:O,transformers:U}=M,H=r??s,T=_??M.submitDebounceMs,z=x??k.messages.submit,{fieldGroups:I,fieldByCode:Q,initialValues:j}=lt(e),{fieldStates:F,setFieldState:C}=dt(I),V=d.useRef(new Map),P=d.useCallback((R,B,W)=>{if(B&&W){V.current.set(R,{ref:B,...W});return}V.current.delete(R)},[]),{buildProcessedValues:Z}=ut({formInstance:t,fieldByCode:Q,relatedData:n,transformers:U,nestedFormRefs:V}),$=d.useRef(!1),[Y,G]=d.useState(!1),[ae,Le]=d.useState(!1);d.useEffect(()=>{const R=Object.fromEntries(Object.entries(j).filter(([W])=>{const D=Q.get(W)?.field?.type?.code;return D!=="form"&&D!=="multiple-form"}));if(Object.keys(R).length===0)return;const B=U.normalizeInitialValues?U.normalizeInitialValues(R,I):R;t.setFieldsValue(B)},[Q,I,t,j,U]);const ce=d.useCallback(async()=>{if(!$.current){$.current=!0,G(!0);try{let R=await Z();try{o&&(Le(!0),await E.request({method:"POST",url:o,data:R}));const D=await i?.(R);if(D===!1)return;D&&typeof D=="object"&&(R=D)}catch(D){console.error(D);return}finally{Le(!1)}const B=await E.request({method:e.method,url:e.action,data:R});t.resetFields(I.filter(D=>!D.is_hidden).map(D=>D.code));const W=K.submitResponse(B.data);m&&W.redirectUrl&&(h??N)(W.redirectUrl,"_blank"),a?.({values:R,response:B.data,data:W.data??B.data})}catch(R){const B=R;v.error(B?.response?.data?.message??k.messages.submitError),p?.(R)}finally{$.current=!1,G(!1)}}},[Z,E,I,e.action,e.method,t,k.messages.submitError,m,v,i,h,p,a,K,N,o]);d.useImperativeHandle(w,()=>({submit:ce,getProcessedValues:Z,isSubmitting:()=>$.current}),[Z,ce]);const Oe=d.useMemo(()=>fe(()=>{ce()},T),[ce,T]),_t=d.useCallback((R,B)=>{Object.keys(R).forEach(W=>{const D=Dt(W,I,t.getFieldsValue());D.length>0&&t.resetFields(D)}),u?.(R,B)},[I,t,u]),Ie=d.useCallback(R=>c.jsx(at,{group:R,formInstance:t,fieldState:F[R.code],setFieldState:C,uploadUrl:H,readOnly:y,size:f,registerNestedForm:P},R.id),[F,t,P,y,H,C,f]),bt=O.layout?O.layout({fieldGroups:I,fieldStates:F,renderField:Ie,gutter:g,defaultColSpan:S,size:f}):c.jsx(ct,{fieldGroups:I,fieldStates:F,renderField:Ie,gutter:g,defaultColSpan:S,size:f}),gt=!l&&!y&&(O.submitActions?O.submitActions({onSubmit:Oe,loading:Y||ae,label:z}):c.jsx(b.Flex,{justify:"flex-end",children:c.jsx(b.Button,{type:"primary",onClick:Oe,loading:Y||ae,children:z})}));return c.jsxs(b.Form,{layout:"vertical",form:t,size:f,component:A?!1:void 0,onValuesChange:_t,children:[bt,gt]})});he.displayName="DynamicForm";const de=new Map,Wt=3e4;function $t(e){const t=de.get(e);if(t){if(Date.now()>t.expiresAt){de.delete(e);return}return t.error}}function Ke(e,t){de.set(e,{error:t,expiresAt:Date.now()+Wt})}function se(e,t,n=!0){const r=L(),[s,o]=d.useState(),[i,a]=d.useState(!1),[p,m]=d.useState(),h=d.useRef(t),f=d.useRef(r);h.current=t,f.current=r;const l=ne(e);return d.useEffect(()=>{if(!n){o(void 0),m(void 0),a(!1);return}const y=$t(l);if(y!==void 0){m(y),a(!1);return}const _=new AbortController;return a(!0),m(void 0),(async()=>{try{const S=await re(f.current,"viewCache",l,x=>h.current(x),_.signal);_.signal.aborted||(o(S),m(void 0))}catch(S){_.signal.aborted||(Ke(l,S),m(S))}finally{_.signal.aborted||a(!1)}})(),()=>_.abort()},[n,l]),{data:s,isLoading:i,error:p,refetch:async()=>{if(de.delete(l),!n)return;const y=new AbortController;a(!0),m(void 0);try{const _=await re(f.current,"viewCache",l,g=>h.current(g),y.signal);return o(_),_}catch(_){throw Ke(l,_),m(_),_}finally{a(!1)}}}}const zt=({value:e,code:t,modeConfig:n})=>{const{client:r,renderers:s,i18n:o}=L(),i=d.useMemo(()=>(Array.isArray(e)?e:[e]).filter(Boolean),[e]),{data:a,isLoading:p,error:m}=se(["api_detail",t,i,n?.url,n?.method],async l=>(await Promise.all(i.map(async y=>{const _=oe(n?.url||"",{id:y});return(await r.request({method:n?.method,url:_,signal:l})).data}))).filter(Boolean),!!(i.length&&n?.url)),h=(l,u,y)=>s.link?s.link({url:l,label:u,data:y}):c.jsx("a",{href:l,target:"_blank",rel:"noreferrer",children:u}),f=l=>{const u=n?.mapping_attr?.map(y=>l?.[y]).join(" - ");if(n?.link){const y=oe(n.link,l);return h(y,u,l)}return u};return p?c.jsx(c.Fragment,{children:s.viewLoading?.()??c.jsx(b.Spin,{size:"small"})}):m?c.jsx(c.Fragment,{children:s.viewError?.(m)??o.messages.viewError}):a?.length?c.jsx(c.Fragment,{children:a.map((l,u)=>c.jsx("div",{children:f(l)},u))}):c.jsx(c.Fragment,{children:s.viewEmpty?.()??o.messages.viewEmpty})},Re=d.memo(zt),Ht=({value:e,code:t,modeConfig:n})=>{const{client:r,renderers:s,i18n:o}=L(),{data:i,isLoading:a,error:p}=se(["api_ids",t,e,n?.url,n?.method],async f=>{const l=n?.method||"GET",u=l.toUpperCase()==="POST",y=Array.isArray(e)?e:[e],g=(await r.request({method:l,url:n?.url||"",data:u?{ids:y}:void 0,params:u?void 0:{ids:y},signal:f})).data,S=n?.data_path?X(g,n.data_path):g;return Array.isArray(S)?S:g},!!(e&&n?.url)),m=(f,l,u)=>s.link?s.link({url:f,label:l,data:u}):c.jsx("a",{href:f,target:"_blank",rel:"noreferrer",children:l}),h=f=>{const l=n?.mapping_attr?.map(u=>f?.[u]).join(" - ");if(n?.link){const u=oe(n.link,f);return m(u,l,f)}return l};return a?c.jsx(c.Fragment,{children:s.viewLoading?.()??c.jsx(b.Spin,{size:"small"})}):p?c.jsx(c.Fragment,{children:s.viewError?.(p)??o.messages.viewError}):i?Array.isArray(e)?c.jsx(b.Flex,{vertical:!0,children:(Array.isArray(i)?i:[i]).map((f,l)=>c.jsx("div",{children:h(f)},f.id??l))}):h(Array.isArray(i)?i[0]:i):c.jsx(c.Fragment,{children:s.viewEmpty?.()??o.messages.viewEmpty})},Ee=d.memo(Ht),Yt=({value:e,code:t,modeConfig:n,viewConfig:r})=>{const{client:s,renderers:o,i18n:i}=L(),a=d.useMemo(()=>n??(r?we(r):void 0),[n,r]),p=d.useMemo(()=>["api_view",t,e,a?.url,a?.method,a?.data_path],[t,e,a?.url,a?.method,a?.data_path]),m=d.useCallback(async _=>a?Ye(e,a,g=>s.request({...g,signal:_})):[],[s,a,e]),{data:h,isLoading:f,error:l}=se(p,m,!!(e&&a?.url)),u=(_,g,S)=>o.link?o.link({url:_,label:g,data:S}):c.jsx("a",{href:_,target:"_blank",rel:"noreferrer",children:g}),y=(_,g)=>{if(!a)return null;const S=ve(_,a),x=je(_,a),A=x?u(x,S,_):S;return c.jsx("div",{children:A},_.id??g)};return f?c.jsx(c.Fragment,{children:o.viewLoading?.()??c.jsx(b.Spin,{size:"small"})}):l?c.jsx(c.Fragment,{children:o.viewError?.(l)??i.messages.viewError}):h?.length?a?.result_type==="object"&&h.length===1?y(h[0],0):c.jsx(b.Flex,{vertical:!0,children:h.map(y)}):c.jsx(c.Fragment,{children:o.viewEmpty?.()??i.messages.viewEmpty})},Me=d.memo(Yt),Jt={whiteSpace:"normal",wordBreak:"break-word",verticalAlign:"top"},Ve=({group:e,value:t,formValues:n={}})=>{const r=L(),s=e.additional_config?.multiple_form,o=s?.config_url,i=s?.method??"GET",{data:a,isLoading:p,error:m}=me([o,i],async()=>{if(!o)throw new Error("Missing additional_config.multiple_form.config_url");const u=await r.client.request({method:i,url:o});return r.parsers.formConfigResponse(u.data)},{enabled:!!o}),h=d.useMemo(()=>{if(!a)return[];if(t&&typeof t=="object"&&!Array.isArray(t)){const u=t;if(a.code in u&&Array.isArray(u[a.code]))return u[a.code]}return Array.isArray(t)?t:ke(e,{...n,[e.code]:t},a.code)},[n,e,a,t]),f=d.useMemo(()=>a?[...a.field_groups].filter(u=>!u.is_hidden).sort((u,y)=>Number(u.position??0)-Number(y.position??0)).map(u=>({key:u.code,title:u.label,dataIndex:u.code,width:140,onCell:()=>({style:Jt}),render:(y,_)=>c.jsx(Te,{code:u.code,value:_[u.code],fieldGroup:u,formValues:_})})):[],[a]),l=d.useMemo(()=>h.map((u,y)=>({key:y,...u})),[h]);return o?p?c.jsx(b.Alert,{type:"info",message:"Loading...",showIcon:!0}):m||!a?c.jsx(b.Alert,{type:"error",message:"Failed to load nested form",showIcon:!0}):h.length===0?"-":c.jsx("div",{style:{width:"100%",maxWidth:"100%",overflowX:"auto",overflowY:"hidden"},children:c.jsx(b.Table,{size:"small",bordered:!0,pagination:{pageSize:5,hideOnSinglePage:!0,size:"small"},columns:f,dataSource:l})}):c.jsx(b.Alert,{type:"warning",message:"Missing multiple_form config_url",showIcon:!0})},Xt=({value:e,fieldGroup:t,formValues:n={}})=>{const r=L(),{renderers:s}=r,o=d.useMemo(()=>Se(e,t.metas),[t.metas,e]),i=!!(t.is_option_api&&t.option_config?.url),a=i&&!o&&!q(e),{data:p,isLoading:m,error:h}=se(["selectLikeView",t.code,t.option_config?.url,t.option_config?.method,e,n],async f=>{const l=pe(t,n),u=t.option_config?.method?.toUpperCase()==="GET"||!t.option_config?.method,_={[t.option_config?.value_attr||"value"]:e},g=await r.client.request({method:t.option_config?.method||"GET",url:t.option_config?.url||"",params:u?{...l?.params,filter:{...l?.params?.filter,..._}}:l?.params,data:u?l?.data:{...l?.data,filter:{...l?.data?.filter,..._}},signal:f});return r.parsers.optionResponse(g.data,t)},a);return q(e)?c.jsx(c.Fragment,{children:s.viewEmpty?.()??"-"}):o?c.jsx(c.Fragment,{children:o}):i?m?c.jsx(c.Fragment,{children:s.viewLoading?.()??c.jsx(b.Spin,{size:"small"})}):h?c.jsx(c.Fragment,{children:s.viewError?.(h)??ee(e,t)??String(e)}):c.jsx(c.Fragment,{children:ee(e,t,p)??String(e)}):c.jsx(c.Fragment,{children:ee(e,t)??String(e)})},Qt=d.memo(Xt),Zt=({code:e,value:t,fieldGroup:n,formValues:r})=>{const s=n?.field?.type?.code,o=r??{[e]:t};if(s==="form"&&n)return c.jsx(De,{group:n,value:t,formValues:o});if(s==="multiple-form"&&n)return c.jsx(Ve,{group:n,value:t,formValues:o});const i=n?.additional_config?.view_value,a=t==null?"":String(t);if((s==="select"||s==="radio"||s==="checkbox")&&n&&!i?.mode)return c.jsx(Qt,{value:t,fieldGroup:n,formValues:o});if(s==="datetime"&&n&&!i?.mode)return c.jsx(c.Fragment,{children:Je(t,n)??(q(t)?"-":a)});switch(i?.mode){case"raw":return a;case"api":return c.jsx(Me,{code:e,value:a,viewConfig:i});case"api_ids":{const p=i?.api_ids;return c.jsx(Ee,{code:e,value:a,modeConfig:p})}case"api_detail":{const p=i?.api_detail;return c.jsx(Re,{code:e,value:a,modeConfig:p})}default:return a}},Te=d.memo(Zt),Gt={flexShrink:0,whiteSpace:"nowrap",color:"rgba(0, 0, 0, 0.45)"},en={flex:1,minWidth:0,whiteSpace:"normal",wordBreak:"break-word"},tn={display:"flex",alignItems:"flex-start",gap:12,marginBottom:8},nn=({fieldGroups:e,values:t})=>{const n=d.useMemo(()=>[...e].sort((r,s)=>Number(r.position??0)-Number(s.position??0)).filter(r=>!r.is_hidden&&r.code in t).map(r=>({key:r.code,label:r.label,content:c.jsx(Te,{code:r.code,value:t[r.code],fieldGroup:r,formValues:t})})),[e,t]);return n.length===0?c.jsx(c.Fragment,{children:"-"}):c.jsx("div",{style:{width:"100%"},children:n.map(r=>c.jsxs("div",{style:tn,children:[c.jsxs("div",{style:Gt,children:[r.label,":"]}),c.jsx("div",{style:en,children:r.content})]},r.key))})},De=({group:e,value:t,formValues:n={}})=>{const r=L(),s=e.additional_config?.form?.config_url,o=e.additional_config?.form?.method??"GET",{data:i,isLoading:a,error:p}=me([s,o],async()=>{if(!s)throw new Error("Missing additional_config.form.config_url");const h=await r.client.request({method:o,url:s});return r.parsers.formConfigResponse(h.data)},{enabled:!!s}),m=d.useMemo(()=>{if(i){if(t&&typeof t=="object"&&!Array.isArray(t)){const h=t;if(i.code in h){const f=h[i.code];return f&&typeof f=="object"&&!Array.isArray(f)?f:void 0}return h}return Qe(e,{...n,[e.code]:t},i.code)}},[n,e,i,t]);return s?a?c.jsx(b.Alert,{type:"info",message:"Loading...",showIcon:!0}):p||!i?c.jsx(b.Alert,{type:"error",message:"Failed to load nested form",showIcon:!0}):!m||Object.keys(m).length===0?"-":c.jsx(nn,{fieldGroups:i.field_groups,values:m}):c.jsx(b.Alert,{type:"warning",message:"Missing nested form config_url",showIcon:!0})};function rn(e){return!!(e.option_config&&e.is_option_api)}function sn(e,t){const n=L(),r=ne(["viewModeOptions",e.map(o=>o.code),t]),{data:s}=se([r],async o=>{const i={};return await Promise.all(e.map(async a=>{if(!a.option_config?.url)return;const p=pe(a,t),m=a.option_config.method?.toUpperCase()==="GET"||!a.option_config.method,h=await n.client.request({method:a.option_config.method||"GET",url:a.option_config.url,params:m?p?.params:void 0,data:m?void 0:p?.data,signal:o});i[a.code]={optionList:n.parsers.optionResponse(h.data,a)}})),i},e.length>0);return s??{}}const on=({formConfig:e,formValues:t})=>{const n=e?.form?.field_groups??[],r=d.useMemo(()=>n.filter(rn),[n]),s=sn(r,t);return d.useMemo(()=>n.filter(i=>!i.is_hidden).map(i=>{const a=t?.[i.code],p=i.field?.type?.code,m=i.additional_config?.view_value,h=m?.mode;if(p==="form")return{key:i.code,label:i.label,rawValue:a,viewValue:c.jsx(De,{group:i,value:a,formValues:t}),field_group:i};if(p==="multiple-form")return{key:i.code,label:i.label,rawValue:a,viewValue:c.jsx(Ve,{group:i,value:a,formValues:t}),field_group:i};if(h==="api"&&m)return{key:i.code,label:i.label,rawValue:a,viewValue:c.jsx(Me,{code:i.code,value:a,viewConfig:m}),field_group:i};if(h==="api_ids"&&m?.api_ids)return{key:i.code,label:i.label,rawValue:a,viewValue:c.jsx(Ee,{code:i.code,value:a,modeConfig:m.api_ids}),field_group:i};if(h==="api_detail"&&m?.api_detail)return{key:i.code,label:i.label,rawValue:a,viewValue:c.jsx(Re,{code:i.code,value:a,modeConfig:m.api_detail}),field_group:i};const f=s[i.code]??{};return{key:i.code,label:i.label,rawValue:a,viewValue:Xe(i,a,f),field_group:i}}),[s,n,t])},Pe={submit:"Save",submitError:"Failed to submit form",inputPlaceholder:e=>`Enter ${e}`,selectPlaceholder:e=>`Select ${e}`,optionLoading:"Loading...",optionError:"Failed to load options",uploadError:"Upload failed",viewLoading:"Loading...",viewEmpty:"-",viewError:"Failed to load"},an={messages:Pe},ft=e=>{if(Array.isArray(e))return e;if(e&&typeof e=="object"&&"items"in e&&Array.isArray(e.items))return e.items;if(e&&typeof e=="object"&&"data"in e&&e.data&&typeof e.data=="object"&&"items"in(e.data??{})){const t=e.data;return Array.isArray(t.items)?t.items:[]}return[]},mt=e=>({redirectUrl:e?.redirect_after_create,data:e}),pt=(e,t)=>t?.dataPath?X(e,t.dataPath):e,yt=e=>e,ie={optionResponse:ft,submitResponse:mt,viewResponse:pt,formConfigResponse:yt},ht=(e,t="_blank")=>{window.open(e,t)},_e={upload:async()=>{throw new Error("Upload adapter is not configured")},remove:async()=>!1};function cn({children:e,client:t,upload:n,i18n:r,parsers:s,renderers:o={},transformers:i={},cache:a,submitDebounceMs:p=200,redirectHandler:m,requestClient:h,uploadAdapter:f,deleteUploadAdapter:l,messages:u,optionResponseParser:y,customFieldRenderers:_}){const g=d.useRef(new Map),S=d.useRef(new Map),x=d.useMemo(()=>{const A=t??{request:h??(()=>{throw new Error("DynamicFormProvider requires client or requestClient")})},w=_?Object.entries(_).map(([k,E])=>({match:k,render:E})):[],v={...Pe,...r?.messages,...u},M={..._e,...n,upload:n?.upload??f??_e.upload,remove:n?.remove??(l?k=>l(k.path):_e.remove)};return{client:A,upload:M,i18n:{messages:v},parsers:{optionResponse:s?.optionResponse??y??ie.optionResponse,submitResponse:s?.submitResponse??ie.submitResponse,viewResponse:s?.viewResponse??ie.viewResponse,formConfigResponse:s?.formConfigResponse??ie.formConfigResponse},renderers:{...o,fields:[...o.fields??[],...w]},transformers:i,cache:{enabled:a?.enabled??!0,ttlMs:a?.ttlMs??6e4},submitDebounceMs:p,redirectHandler:m??ht,optionCache:g.current,viewCache:S.current}},[t,h,n,f,l,r?.messages,u,s?.optionResponse,s?.submitResponse,s?.viewResponse,s?.formConfigResponse,y,o,_,i,a?.enabled,a?.ttlMs,p,m]);return c.jsx(ge.Provider,{value:x,children:e})}function ln(e){return{request:async t=>({data:(await e({method:t.method,url:t.url,params:t.params,data:t.data,signal:t.signal,headers:t.headers,onUploadProgress:t.onUploadProgress})).data})}}exports.ApiDetailItem=Re;exports.ApiItem=Ee;exports.ApiViewItem=Me;exports.DefaultLayout=ct;exports.DynamicForm=he;exports.DynamicFormProvider=cn;exports.FormItem=at;exports.MetaItemValue=Te;exports.MultipleNestedForm=rt;exports.MultipleNestedFormView=Ve;exports.NestedForm=et;exports.NestedFormView=De;exports.buildApiViewRequests=He;exports.buildCacheKey=ne;exports.cachedRequest=re;exports.createAxiosDynamicFormClient=ln;exports.createNestedDynamicFormData=Vt;exports.debounce=fe;exports.defaultFormConfigResponseParser=yt;exports.defaultI18n=an;exports.defaultMessages=Pe;exports.defaultOptionResponseParser=ft;exports.defaultParsers=ie;exports.defaultRedirectHandler=ht;exports.defaultSubmitResponseParser=mt;exports.defaultViewResponseParser=pt;exports.extractDependencyFields=Ge;exports.extractMultipleNestedFormValues=ke;exports.extractNestedFormValue=Qe;exports.extractViewData=xe;exports.fetchApiViewItems=Ye;exports.fillTemplate=oe;exports.getByPath=X;exports.getCached=tt;exports.getMappedLabel=ve;exports.getMappedLink=je;exports.getNestedFormCodeHint=te;exports.getNestedSubmitContainerKey=ye;exports.isEmptyValue=q;exports.mapOptionToSelectItem=We;exports.mapOptions=$e;exports.normalizeApiViewConfig=we;exports.normalizeMetaForForm=Ce;exports.parseFormValues=Ze;exports.replaceTemplateInObject=J;exports.resolveApiOptionMeta=pe;exports.resolveFieldRenderer=Ne;exports.resolveFieldRendererFromMap=Ue;exports.resolveFieldViewValue=Xe;exports.resolveViewValueConfig=be;exports.setCache=nt;exports.unwrapMultipleFormValueForEdit=Fe;exports.unwrapSingleFormValueForEdit=Ae;exports.useCachedViewRequest=se;exports.useDependencyValues=it;exports.useDynamicField=st;exports.useDynamicFormContext=L;exports.useDynamicFormContextOptional=wt;exports.useDynamicOptions=ot;exports.useFieldGroups=lt;exports.useFieldStates=dt;exports.useProcessedValues=ut;exports.useViewMode=on;
|
package/dist/index.d.ts
CHANGED
|
@@ -5,10 +5,12 @@ import { ForwardRefExoticComponent } from 'react';
|
|
|
5
5
|
import { JSX } from 'react';
|
|
6
6
|
import { JSXElementConstructor } from 'react';
|
|
7
7
|
import { MemoExoticComponent } from 'react';
|
|
8
|
+
import { MutableRefObject } from 'react';
|
|
8
9
|
import { ReactElement } from 'react';
|
|
9
10
|
import { ReactNode } from 'react';
|
|
10
11
|
import { ReactPortal } from 'react';
|
|
11
12
|
import { RefAttributes } from 'react';
|
|
13
|
+
import { RefObject } from 'react';
|
|
12
14
|
import { SetStateAction } from 'react';
|
|
13
15
|
import { SizeType } from 'antd/es/config-provider/SizeContext';
|
|
14
16
|
|
|
@@ -54,6 +56,17 @@ export declare interface AdditionalConfig {
|
|
|
54
56
|
search_keyword?: boolean;
|
|
55
57
|
searchDebounceMs?: number;
|
|
56
58
|
};
|
|
59
|
+
form?: {
|
|
60
|
+
config_url: string;
|
|
61
|
+
method?: "GET" | "POST" | string;
|
|
62
|
+
submit_container_key?: string;
|
|
63
|
+
};
|
|
64
|
+
multiple_form?: {
|
|
65
|
+
config_url: string;
|
|
66
|
+
method?: "GET" | "POST" | string;
|
|
67
|
+
primary_field: string;
|
|
68
|
+
submit_container_key?: string;
|
|
69
|
+
};
|
|
57
70
|
view_value?: ViewValueConfig;
|
|
58
71
|
}
|
|
59
72
|
|
|
@@ -133,6 +146,8 @@ export declare function cachedRequest<T>(ctx: Pick<DynamicFormContextValue, "opt
|
|
|
133
146
|
|
|
134
147
|
export declare function createAxiosDynamicFormClient(axiosInstance: AxiosLike): DynamicFormClient;
|
|
135
148
|
|
|
149
|
+
export declare function createNestedDynamicFormData(form: Form): DynamicFormData;
|
|
150
|
+
|
|
136
151
|
export declare type CustomFieldRenderer = (group: FieldGroup, context: {
|
|
137
152
|
state: FieldState;
|
|
138
153
|
options?: Record<string, unknown>[];
|
|
@@ -147,6 +162,8 @@ export declare type CustomFieldRenderer = (group: FieldGroup, context: {
|
|
|
147
162
|
|
|
148
163
|
export declare function debounce<T extends (...args: never[]) => void>(fn: T, delay: number): (...args: Parameters<T>) => void;
|
|
149
164
|
|
|
165
|
+
export declare const defaultFormConfigResponseParser: (response: unknown) => Form;
|
|
166
|
+
|
|
150
167
|
export declare const defaultI18n: DynamicFormI18n;
|
|
151
168
|
|
|
152
169
|
export declare function DefaultLayout({ fieldGroups, fieldStates, renderField, gutter, defaultColSpan, }: LayoutRendererProps): JSX.Element;
|
|
@@ -233,6 +250,7 @@ export declare type DynamicFormParsers = {
|
|
|
233
250
|
optionResponse: OptionResponseParser;
|
|
234
251
|
submitResponse: SubmitResponseParser;
|
|
235
252
|
viewResponse: ViewResponseParser;
|
|
253
|
+
formConfigResponse: FormConfigResponseParser;
|
|
236
254
|
};
|
|
237
255
|
|
|
238
256
|
export declare type DynamicFormProps = {
|
|
@@ -254,6 +272,7 @@ export declare type DynamicFormProps = {
|
|
|
254
272
|
gutter?: [number, number];
|
|
255
273
|
defaultColSpan?: number;
|
|
256
274
|
submitButtonLabel?: string;
|
|
275
|
+
disableHtmlFormWrapper?: boolean;
|
|
257
276
|
/** @deprecated use uploadUrl */
|
|
258
277
|
uploadResourceUrl?: string;
|
|
259
278
|
};
|
|
@@ -335,6 +354,10 @@ export declare type DynamicUploadFile = {
|
|
|
335
354
|
|
|
336
355
|
export declare function extractDependencyFields(group: FieldGroup): string[];
|
|
337
356
|
|
|
357
|
+
export declare function extractMultipleNestedFormValues(fieldGroup: FieldGroup, formValues: Record<string, unknown>, formCode: string): Record<string, unknown>[];
|
|
358
|
+
|
|
359
|
+
export declare function extractNestedFormValue(fieldGroup: FieldGroup, formValues: Record<string, unknown>, formCode: string, fieldType: "form" | "multiple-form"): Record<string, unknown> | undefined;
|
|
360
|
+
|
|
338
361
|
export declare function extractViewData(response: unknown, config: ApiViewConfig): Record<string, unknown>[];
|
|
339
362
|
|
|
340
363
|
export declare function fetchApiViewItems(value: unknown, config: ApiViewConfig, request: (spec: ApiViewRequestSpec & {
|
|
@@ -446,7 +469,9 @@ export declare interface Form {
|
|
|
446
469
|
field_groups: FieldGroup[];
|
|
447
470
|
}
|
|
448
471
|
|
|
449
|
-
export declare
|
|
472
|
+
export declare type FormConfigResponseParser = (response: unknown) => Form;
|
|
473
|
+
|
|
474
|
+
export declare const FormItem: MemoExoticComponent<({ group, formInstance, fieldState, setFieldState, uploadUrl, readOnly, size, registerNestedForm, ...formItemProps }: FormItemPropsExtended) => JSX.Element>;
|
|
450
475
|
|
|
451
476
|
declare type FormItemPropsExtended = {
|
|
452
477
|
group: FieldGroup;
|
|
@@ -456,6 +481,7 @@ declare type FormItemPropsExtended = {
|
|
|
456
481
|
uploadUrl?: string;
|
|
457
482
|
readOnly?: boolean;
|
|
458
483
|
size?: SizeType;
|
|
484
|
+
registerNestedForm?: RegisterNestedForm;
|
|
459
485
|
} & FormItemProps;
|
|
460
486
|
|
|
461
487
|
export declare function getByPath(obj: unknown, path: string): unknown;
|
|
@@ -469,6 +495,10 @@ export declare function getMappedLabel(data: Record<string, unknown>, config: Ap
|
|
|
469
495
|
|
|
470
496
|
export declare function getMappedLink(data: Record<string, unknown>, config: ApiViewConfig): string | null;
|
|
471
497
|
|
|
498
|
+
export declare function getNestedFormCodeHint(fieldGroup: FieldGroup): string | undefined;
|
|
499
|
+
|
|
500
|
+
export declare function getNestedSubmitContainerKey(fieldGroup: FieldGroup): string;
|
|
501
|
+
|
|
472
502
|
export declare type GetUploadPayload = (options: UploadAdapterOptions) => FormData | Record<string, unknown>;
|
|
473
503
|
|
|
474
504
|
export declare function isEmptyValue(value: unknown): boolean;
|
|
@@ -514,12 +544,62 @@ export declare type MetaItem = {
|
|
|
514
544
|
deleted_at: string | null;
|
|
515
545
|
};
|
|
516
546
|
|
|
517
|
-
export declare const MetaItemValue: MemoExoticComponent<({ code, value, fieldGroup, }: {
|
|
547
|
+
export declare const MetaItemValue: MemoExoticComponent<({ code, value, fieldGroup, formValues, }: {
|
|
518
548
|
code: string;
|
|
519
|
-
value:
|
|
549
|
+
value: unknown;
|
|
520
550
|
fieldGroup?: FieldGroup;
|
|
551
|
+
formValues?: Record<string, unknown>;
|
|
521
552
|
}) => string | JSX.Element>;
|
|
522
553
|
|
|
554
|
+
export declare const MultipleNestedForm: ({ group, value, onChange, disabled, readOnly, registerNestedForm, }: MultipleNestedFormProps) => JSX.Element;
|
|
555
|
+
|
|
556
|
+
declare type MultipleNestedFormProps = {
|
|
557
|
+
group: FieldGroup;
|
|
558
|
+
value?: Record<string, unknown>[];
|
|
559
|
+
onChange?: (value: Record<string, unknown>[]) => void;
|
|
560
|
+
disabled?: boolean;
|
|
561
|
+
readOnly?: boolean;
|
|
562
|
+
registerNestedForm?: RegisterNestedForm;
|
|
563
|
+
};
|
|
564
|
+
|
|
565
|
+
export declare const MultipleNestedFormView: ({ group, value, formValues, }: MultipleNestedFormViewProps) => JSX.Element | "-";
|
|
566
|
+
|
|
567
|
+
declare type MultipleNestedFormViewProps = {
|
|
568
|
+
group: FieldGroup;
|
|
569
|
+
value?: unknown;
|
|
570
|
+
formValues?: Record<string, unknown>;
|
|
571
|
+
};
|
|
572
|
+
|
|
573
|
+
export declare const NestedForm: ({ group, value, onChange, disabled, readOnly, registerNestedForm, }: NestedFormProps) => JSX.Element;
|
|
574
|
+
|
|
575
|
+
export declare type NestedFormFieldType = "form" | "multiple-form";
|
|
576
|
+
|
|
577
|
+
declare type NestedFormProps = {
|
|
578
|
+
group: FieldGroup;
|
|
579
|
+
value?: Record<string, unknown>;
|
|
580
|
+
onChange?: (value: Record<string, unknown>) => void;
|
|
581
|
+
disabled?: boolean;
|
|
582
|
+
readOnly?: boolean;
|
|
583
|
+
registerNestedForm?: RegisterNestedForm;
|
|
584
|
+
};
|
|
585
|
+
|
|
586
|
+
export declare type NestedFormRegistration = NestedFormRegistrationMeta & {
|
|
587
|
+
ref: RefObject<DynamicFormRef | null>;
|
|
588
|
+
};
|
|
589
|
+
|
|
590
|
+
export declare type NestedFormRegistrationMeta = {
|
|
591
|
+
formCode: string;
|
|
592
|
+
fieldType: NestedFormFieldType;
|
|
593
|
+
};
|
|
594
|
+
|
|
595
|
+
export declare const NestedFormView: ({ group, value, formValues, }: NestedFormViewProps) => JSX.Element | "-";
|
|
596
|
+
|
|
597
|
+
declare type NestedFormViewProps = {
|
|
598
|
+
group: FieldGroup;
|
|
599
|
+
value?: unknown;
|
|
600
|
+
formValues?: Record<string, unknown>;
|
|
601
|
+
};
|
|
602
|
+
|
|
523
603
|
export declare function normalizeApiViewConfig(viewConfig?: ViewValueConfig): ApiViewConfig | undefined;
|
|
524
604
|
|
|
525
605
|
export declare function normalizeMetaForForm(meta: Record<string, unknown>, fieldGroups: FieldGroup[]): Record<string, unknown>;
|
|
@@ -541,6 +621,8 @@ export declare function parseFormValues<T extends Record<string, unknown>>(formV
|
|
|
541
621
|
|
|
542
622
|
export declare type RedirectHandler = (url: string, target?: string) => void;
|
|
543
623
|
|
|
624
|
+
export declare type RegisterNestedForm = (code: string, ref: RefObject<DynamicFormRef | null> | null, meta?: NestedFormRegistrationMeta | null) => void;
|
|
625
|
+
|
|
544
626
|
export declare function replaceTemplateInObject(obj: Record<string, unknown>, dependencyValues: Record<string, unknown>): Record<string, unknown>;
|
|
545
627
|
|
|
546
628
|
export declare type RequestClient = (config: RequestConfig) => Promise<{
|
|
@@ -599,6 +681,10 @@ export declare type SubmitSuccessPayload = {
|
|
|
599
681
|
data: unknown;
|
|
600
682
|
};
|
|
601
683
|
|
|
684
|
+
export declare function unwrapMultipleFormValueForEdit(fieldGroup: FieldGroup, rawValue: unknown, formCode?: string): Record<string, unknown>[];
|
|
685
|
+
|
|
686
|
+
export declare function unwrapSingleFormValueForEdit(fieldGroup: FieldGroup, rawValue: unknown, formCode?: string): Record<string, unknown>;
|
|
687
|
+
|
|
602
688
|
export declare type UploadAdapter = (options: UploadAdapterOptions) => Promise<DynamicUploadFile>;
|
|
603
689
|
|
|
604
690
|
export declare type UploadAdapterOptions = {
|
|
@@ -624,13 +710,14 @@ export declare function useCachedViewRequest<T>(cacheKeyParts: unknown[], fetche
|
|
|
624
710
|
export declare function useDependencyValues(group: FieldGroup, formInstance: FormInstance): Record<string, unknown>;
|
|
625
711
|
|
|
626
712
|
export declare const useDynamicField: ({ formInstance, uploadUrl, setFieldState, }: UseDynamicFieldOptions) => {
|
|
627
|
-
getDynamicField: (group: FieldGroup, { state, options, optionsLoading, optionsError, onSearchKeyword, readOnly, }: {
|
|
713
|
+
getDynamicField: (group: FieldGroup, { state, options, optionsLoading, optionsError, onSearchKeyword, readOnly, registerNestedForm, }: {
|
|
628
714
|
state: FieldState;
|
|
629
715
|
options?: Record<string, unknown>[];
|
|
630
716
|
optionsLoading?: boolean;
|
|
631
717
|
optionsError?: unknown;
|
|
632
718
|
onSearchKeyword?: (keywords: string) => void;
|
|
633
719
|
readOnly?: boolean;
|
|
720
|
+
registerNestedForm?: RegisterNestedForm;
|
|
634
721
|
}) => string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | ReactPortal | ReactElement<unknown, string | JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | JSX.Element | null | undefined;
|
|
635
722
|
};
|
|
636
723
|
|
|
@@ -666,7 +753,7 @@ export declare function useFieldStates(fieldGroups: FieldGroup[]): {
|
|
|
666
753
|
setFieldState: (code: string, patch: Partial<FieldState>) => void;
|
|
667
754
|
};
|
|
668
755
|
|
|
669
|
-
export declare function useProcessedValues({ formInstance, fieldByCode, relatedData, transformers, }: UseProcessedValuesOptions): {
|
|
756
|
+
export declare function useProcessedValues({ formInstance, fieldByCode, relatedData, transformers, nestedFormRefs, }: UseProcessedValuesOptions): {
|
|
670
757
|
buildProcessedValues: () => Promise<Record<string, unknown>>;
|
|
671
758
|
};
|
|
672
759
|
|
|
@@ -675,6 +762,7 @@ declare type UseProcessedValuesOptions = {
|
|
|
675
762
|
fieldByCode: Map<string, FieldGroup>;
|
|
676
763
|
relatedData?: Record<string, unknown>;
|
|
677
764
|
transformers: DynamicFormTransformers;
|
|
765
|
+
nestedFormRefs: MutableRefObject<Map<string, NestedFormRegistration>>;
|
|
678
766
|
};
|
|
679
767
|
|
|
680
768
|
export declare const useViewMode: ({ formConfig, formValues, }: UseViewModeProps) => ViewColumnField[];
|