@nice2dev/ui-forms 1.1.9 → 1.1.10

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 CHANGED
@@ -1 +1,3 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-CBtq6P2a.cjs");exports.NiceArrayField=e.NiceArrayField;exports.NiceEntityEditor=e.NiceEntityEditor;exports.NiceFormBuilderAI=e.NiceFormBuilderAI;exports.NiceI18nEditor=e.NiceI18nEditor;exports.NiceManifestEditor=e.NiceManifestEditor;exports.NiceModuleEditor=e.NiceModuleEditor;exports.NiceSchemaForm=e.NiceSchemaForm;exports.defineManifestSection=e.defineManifestSection;exports.formBuilderSchemaToNiceFormItems=e.formBuilderSchemaToNiceFormItems;exports.formFieldsToFormItems=e.formFieldsToFormItems;exports.formSchemaToJsonSchema=e.formSchemaToJsonSchema;exports.jsonSchemaToFormItems=e.jsonSchemaToFormItems;exports.schemaToFormItems=e.schemaToFormItems;exports.validateAgainstJsonSchema=e.validateAgainstJsonSchema;exports.validateFormSchema=e.validateFormSchema;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),Te=require("@nice2dev/i18n"),c=require("@nice2dev/ui"),u=require("react"),W=require("@nice2dev/ui-core");function Fe(t){var r,s;const o={text:"text",email:"email",password:"password",phone:"phone",url:"url",textarea:"textarea",number:"number",date:"date",datetime:"datetime",time:"time",select:"select",multiselect:"tags",checkbox:"checkbox",toggle:"toggle",radio:"radio",slider:"slider",rating:"rating",color:"color",file:"file",image:"file"},a=[];for(const i of t.sections)for(const n of i.fields)n.type==="heading"||n.type==="paragraph"||n.type==="divider"||n.type==="spacer"||n.type==="section"||a.push({field:n.name,label:n.label||n.name,type:o[n.type]||"text",placeholder:n.placeholder,hint:n.helpText,defaultValue:n.defaultValue,required:n.required||((r=n.validations)==null?void 0:r.some(d=>d.type==="required")),disabled:n.disabled,readOnly:n.readonly,group:i.title,options:(s=n.options)==null?void 0:s.map(d=>typeof d=="string"?{label:d,value:d}:{label:d.label,value:d.value})});return a}function ce(t){var a;const o={text:"NiceTextInput",textarea:"NiceTextArea",number:"NiceNumberInput",email:"NiceTextInput",password:"NicePasswordInput",date:"NiceDateTimePicker",datetime:"NiceDateTimePicker",time:"NiceDateTimePicker",select:"NiceSelect",multiselect:"NiceTagBox",checkbox:"NiceCheckbox",toggle:"NiceToggle",radio:"NiceRadioGroup",slider:"NiceSlider",rating:"NiceRating",color:"NiceColorPicker"};return{dataField:t.name,label:{text:t.label},editorType:o[t.type]||"NiceTextInput",editorOptions:{placeholder:t.placeholder,disabled:t.disabled,readOnly:t.readonly,...t.props},colSpan:Math.ceil((t.colSpan||12)/6),validationRules:(a=t.validations)==null?void 0:a.map(r=>({type:r.type,message:r.message,...r.value!==void 0?{[r.type]:r.value}:{}})),helpText:t.helpText}}function Ie(t){const o=[];for(const a of t.sections)a.title?o.push({itemType:"group",caption:a.title,colCount:a.columns||2,items:a.fields.map(ce)}):o.push(...a.fields.map(ce));return o}function Ce(t){const o=[];t.version||o.push("Missing schema version"),t.id||o.push("Missing form ID"),(!t.sections||t.sections.length===0)&&o.push("Form must have at least one section");const a=new Set;for(const r of t.sections||[])for(const s of r.fields||[])s.id||o.push(`Field missing ID: ${s.name}`),s.name||o.push(`Field missing name: ${s.id}`),a.has(s.name)&&o.push(`Duplicate field name: ${s.name}`),a.add(s.name);return{valid:o.length===0,errors:o}}function de(t){const{value:o,onChange:a,readOnly:r}=t,[s,i]=u.useState(()=>{try{return o===void 0?"":JSON.stringify(o,null,2)}catch{return""}}),[n,d]=u.useState(null);return u.useEffect(()=>{try{i(o===void 0?"":JSON.stringify(o,null,2))}catch{}},[JSON.stringify(o)]),e.jsxs("div",{className:"nice-schema-form__json-field",children:[e.jsx("textarea",{className:"nice-schema-form__json-textarea",value:s,readOnly:r,spellCheck:!1,rows:Math.min(12,Math.max(3,s.split(`
2
+ `).length)),onChange:y=>{const h=y.target.value;i(h);const g=h.trim();if(g===""){d(null),a(void 0);return}try{a(JSON.parse(g)),d(null)}catch(l){d(l instanceof Error?l.message:"Invalid JSON")}}}),n&&e.jsx("div",{className:"nice-schema-form__json-error",children:n})]})}function Me(t){switch(t){case"email":return"email";case"uri":case"url":return"url";case"date":return"date";case"date-time":return"datetime";case"time":return"time";case"color":return"color";case"password":return"password";case"phone":return"phone";case"data-url":return"file";default:return"text"}}function Ae(t,o,a,r={}){const s={field:t,label:o.title??t,required:a,hint:o.description,defaultValue:o.default};if(o.enum&&o.enum.length>0)return{...s,type:"select",options:o.enum.map(i=>({label:String(i),value:i}))};switch(o.type){case"number":case"integer":return{...s,type:"number"};case"boolean":return{...s,type:"checkbox"};case"string":return{...s,type:Me(o.format)};case"array":{const i=o.items;if(i!=null&&i.enum&&i.enum.length>0)return{...s,type:"tags",options:i.enum.map(n=>({label:String(n),value:String(n)}))};if((i==null?void 0:i.type)==="object"&&i.properties&&r.renderArrayField){const n=r.renderArrayField;return{...s,render:(d,y)=>n(d??[],y,i,s.label)}}return(i==null?void 0:i.type)==="string"||(i==null?void 0:i.type)==="number"||(i==null?void 0:i.type)==="integer"?{...s,type:"tags"}:{...s,render:(n,d)=>e.jsx(de,{value:n,onChange:d})}}case"object":if(r.renderObjectField){const i=r.renderObjectField;return{...s,render:(n,d)=>i(n??{},d,o,s.label)}}return{...s,render:(i,n)=>e.jsx(de,{value:i,onChange:n})};default:return{...s,type:"text"}}}function ae(t,o={}){const{uiSchema:a,renderArrayField:r,renderObjectField:s}=o,i={renderArrayField:r,renderObjectField:s},n=t.properties??{},d=new Set(t.required??[]);return Object.keys(n).map(y=>{const h=Ae(y,n[y],d.has(y),i);return a!=null&&a[y]?{...h,...a[y]}:h})}const $e={text:"text",textarea:"textarea",number:"number",email:"email",password:"password",phone:"phone",url:"url",date:"date",datetime:"datetime",time:"time",select:"select",multiselect:"tags",checkbox:"checkbox",toggle:"toggle",radio:"radio",slider:"slider",rating:"rating",color:"color"};function se(t,o={}){var s,i;const{uiSchema:a}=o,r=[];for(const n of t){if(n.type==="section"&&n.children){for(const h of se(n.children,o))r.push(n.label?{...h,group:n.label}:h);continue}const d=$e[n.type];if(!d)continue;const y={field:n.name,label:n.label,type:d,required:n.required||((s=n.validations)==null?void 0:s.some(h=>h.type==="required")),placeholder:n.placeholder,hint:n.helpText,defaultValue:n.defaultValue,disabled:n.disabled,readOnly:n.readonly,options:(i=n.options)==null?void 0:i.map(h=>typeof h=="string"?{label:h,value:h}:{label:h.label,value:h.value})};r.push(a!=null&&a[n.name]?{...y,...a[n.name]}:y)}return r}function ue(t){return t==null||t===""||Array.isArray(t)&&t.length===0}function oe(t,o){const a=[],r=o.properties??{},s=new Set(o.required??[]);for(const i of Object.keys(r)){const n=r[i],d=t[i];if(s.has(i)&&ue(d)){a.push({field:i,message:`${n.title??i} is required`});continue}if(!ue(d)&&(n.enum&&!n.enum.includes(d)&&a.push({field:i,message:`${n.title??i} must be one of: ${n.enum.join(", ")}`}),(n.type==="number"||n.type==="integer")&&typeof d=="number"&&(n.minimum!==void 0&&d<n.minimum&&a.push({field:i,message:`${n.title??i} must be ≥ ${n.minimum}`}),n.maximum!==void 0&&d>n.maximum&&a.push({field:i,message:`${n.title??i} must be ≤ ${n.maximum}`})),n.type==="string"&&typeof d=="string"&&(n.minLength!==void 0&&d.length<n.minLength&&a.push({field:i,message:`${n.title??i} must be at least ${n.minLength} chars`}),n.maxLength!==void 0&&d.length>n.maxLength&&a.push({field:i,message:`${n.title??i} must be at most ${n.maxLength} chars`}),n.pattern)))try{new RegExp(n.pattern).test(d)||a.push({field:i,message:`${n.title??i} has an invalid format`})}catch{}}return a}const ee="__nafRid";function De(t){return Array.isArray(t)?`[${t.length}]`:t&&typeof t=="object"?"{…}":t==null?"":String(t)}const me=u.forwardRef(function(o,a){const{value:r,defaultValue:s,onChange:i,itemSchema:n,title:d,readOnly:y=!1,columns:h,className:g,style:l,"data-testid":f}=o,[T,$]=c.useControllableState({value:r,defaultValue:s,fallbackValue:[],onChange:i,componentName:"NiceArrayField"}),D=n.properties??{},M=u.useMemo(()=>(h??Object.keys(D)).map(C=>{const N=D[C]??{},w={field:C,header:N.title??C};return N.type==="boolean"?(w.render=V=>V?e.jsx(c.NiceIcon,{name:"check",size:14,title:"true"}):"",w.align="center"):(N.type==="array"||N.type==="object")&&(w.render=V=>De(V)),w}),[n,h]),I=u.useMemo(()=>ae(n),[n]),E=u.useMemo(()=>T.map((K,C)=>({...K,[ee]:String(C)})),[T]),A=K=>{const{[ee]:C,...N}=K;return N},P="nice-array-field"+(g?` ${g}`:"");return e.jsx("div",{ref:a,className:P,style:l,"data-testid":f,children:e.jsx(c.NiceDataGrid,{data:E,keyField:ee,columns:M,editMode:"popup",formItems:I,editFormTitle:d?`${d} — item`:"Edit item",emptyText:`No items${d?` in ${d}`:""}`,compact:!0,onRowAdd:y?void 0:K=>$([...T,A(K)]),onRowEdit:y?void 0:(K,C)=>{const N=Number(K);$(T.map((w,V)=>V===N?A(C):w))},onRowDelete:y?void 0:K=>{const C=Number(K);$(T.filter((N,w)=>w!==C))}})})}),Ke=[{target:".nice-schema-form",titleKey:"tutorial.schemaForm.intro.title",title:"Schema form",contentKey:"tutorial.schemaForm.intro.content",content:"This form is generated from a schema. Required fields and validation errors are flagged; use the JSON toggle for raw editing.",placement:"auto"},{target:'[data-tour="sf-viewtoggle"]',titleKey:"tutorial.schemaForm.viewToggle.title",title:"Form ⇄ JSON",contentKey:"tutorial.schemaForm.viewToggle.content",content:"Switch between the visual form and the raw JSON value — handy for power users and copy/paste.",placement:"bottom"},{target:".nice-schema-form",titleKey:"tutorial.schemaForm.validation.title",title:"Live validation",contentKey:"tutorial.schemaForm.validation.content",content:"Values are validated against the schema as you type; any problems are listed below the form.",placement:"auto"}];function Oe(t){const o=[],a=r=>{for(const s of r){if(s.type==="section"&&s.children){a(s.children);continue}s.required&&o.push({id:`${s.name}-required`,field:s.name,op:"required"});for(const i of s.validations??[])o.push({id:`${s.name}-${i.type}`,field:s.name,op:i.type,value:typeof i.value=="boolean"?void 0:i.value,message:i.message??(i.type==="required"?`${s.label??s.name} is required`:void 0)})}};return a(t),o}function Le(t,o){return c.evaluateValidation(Oe(t),o).filter(a=>a.severity==="error").map(a=>({field:a.field,message:a.message}))}const X=u.forwardRef(function(o,a){const{schema:r,fields:s,uiSchema:i,value:n,defaultValue:d,onChange:y,onValidate:h,showJsonView:g=!1,columns:l=1,labelPosition:f="top",readOnly:T=!1,liveValidation:$=!0,validationRules:D,tutorial:M,className:I,style:E,id:A,"data-testid":P}=o,{t:K}=c.useNiceTranslation(),[C,N]=c.useControllableState({value:n,defaultValue:d,fallbackValue:{},onChange:y,componentName:"NiceSchemaForm"}),[w,V]=u.useState(!1),[z,O]=u.useState(""),[k,J]=u.useState(null),_=u.useMemo(()=>r?ae(r,{uiSchema:i,renderArrayField:(j,b,F,q)=>e.jsx(me,{value:j,onChange:b,itemSchema:F,title:q,readOnly:T})}):s?se(s,{uiSchema:i}):[],[r,s,i,T]),R=u.useMemo(()=>{const j=r?oe(C,r):s?Le(s,C):[];if(D!=null&&D.length){const b=c.evaluateValidation(D,C).filter(F=>F.severity==="error").map(F=>({field:F.field,message:F.message}));return[...j,...b]}return j},[r,s,C,D]);u.useEffect(()=>{h==null||h(R)},[R,h]),u.useEffect(()=>{if(w)try{O(JSON.stringify(C,null,2)),J(null)}catch{}},[w,C]);const p=(j,b)=>{N({...C,[j]:b})},x="nice-schema-form"+(I?` ${I}`:"");return e.jsxs("div",{ref:a,id:A,className:x,style:E,"data-testid":P,children:[M&&e.jsx("div",{className:"nice-schema-form__tutorial",children:e.jsx(c.NiceTutorialButton,{steps:c.resolveTutorial(M,Ke)})}),g&&e.jsxs("div",{className:"nice-schema-form__toolbar","data-tour":"sf-viewtoggle",children:[e.jsx("button",{type:"button",className:"nice-schema-form__tab"+(w?"":" nice-schema-form__tab--active"),onClick:()=>V(!1),children:K("schemaForm.tab.form","Form")}),e.jsx(c.NiceTooltip,{content:K("schemaForm.tab.json.help","Edit the raw JSON value directly"),children:e.jsx("button",{type:"button",className:"nice-schema-form__tab"+(w?" nice-schema-form__tab--active":""),onClick:()=>V(!0),children:K("schemaForm.tab.json","JSON")})})]}),w?e.jsxs("div",{className:"nice-schema-form__json",children:[e.jsx("textarea",{className:"nice-schema-form__json-textarea",value:z,readOnly:T,spellCheck:!1,rows:Math.min(24,Math.max(6,z.split(`
3
+ `).length)),onChange:j=>{const b=j.target.value;O(b);try{const F=JSON.parse(b);J(null),N(F)}catch(F){J(F instanceof Error?F.message:K("schemaForm.invalidJson","Invalid JSON"))}}}),k&&e.jsx("div",{className:"nice-schema-form__json-error",children:k})]}):e.jsx(c.NiceForm,{items:_,data:C,onFieldChange:p,columns:l,labelPosition:f,readOnly:T}),$&&R.length>0&&e.jsx("ul",{className:"nice-schema-form__errors",role:"alert",children:R.map((j,b)=>e.jsx("li",{className:"nice-schema-form__error",children:j.message},`${j.field}-${b}`))})]})}),Re=[{name:"Contact Form",description:"A simple contact form with name, email, and message"},{name:"Registration Form",description:"User registration with username, email, password, and profile info"},{name:"Survey Form",description:"Customer satisfaction survey with rating and feedback fields"},{name:"Order Form",description:"Product order form with shipping address and payment details"},{name:"Job Application",description:"Job application with personal info, experience, and file uploads"},{name:"Event Registration",description:"Event sign-up with attendee info and preferences"}];function qe(t){return{text:"text",string:"text",textarea:"textarea",number:"number",integer:"number",email:"email",password:"password",phone:"phone",tel:"phone",url:"url",date:"date",datetime:"datetime",time:"time",select:"select",dropdown:"select",multiselect:"multiselect",checkbox:"checkbox",boolean:"checkbox",toggle:"toggle",switch:"toggle",radio:"radio",slider:"slider",range:"slider",rating:"rating",stars:"rating",color:"color",file:"file",upload:"file",signature:"signature"}[t.toLowerCase()]||"text"}function Ve(t){return t.map((o,a)=>{var r;return{id:`field_${Date.now()}_${a}`,type:qe(o.type),label:o.label,name:o.field,placeholder:o.placeholder,helperText:o.helpText,required:o.required,options:(r=o.options)==null?void 0:r.map((s,i)=>({value:s.toLowerCase().replace(/\s+/g,"_"),label:s})),validation:o.required?[{type:"required",message:`${o.label} is required`}]:[],width:"100%",order:a}})}const Be=u.forwardRef(function(o,a){const{enableAI:r=!0,aiModel:s,enableGenerate:i=!0,enableSuggestions:n=!0,onGenerate:d,showAIToolbar:y=!0,templates:h=Re,fields:g,onChange:l}=o,[f,T]=u.useState(!1),[$,D]=u.useState(""),[M,I]=u.useState([]),[E,A]=u.useState(g||[]),[P,K]=u.useState(!1),[C,N]=u.useState({}),{t:w}=Te.useNiceTranslation(),V=c.useNiceAI(),{generateForm:z,isLoading:O}=c.useFormGeneration(),k=r&&V.isConfigured,J=u.useCallback(async b=>{if(!k||!i||!b.trim())return[];try{const F=await z(b);return I(F),d==null||d(b,F),F}catch{return[]}},[k,i,z,d]),_=u.useCallback(b=>{const F=Ve(b);A(q=>[...q,...F]),l==null||l([...E,...F]),T(!1),I([]),D("")},[l]),R=u.useCallback(()=>E,[E]),p=u.useCallback(()=>{A([]),l==null||l([])},[l]),x=b=>{D(b.description),K(!1),J(b.description)};u.useImperativeHandle(a,()=>({generateForm:J,getFields:R,applyFields:_,clearFields:p}));const j=b=>({text:"edit",textarea:"file",number:"hash",email:"mail",password:"lock",phone:"phone",date:"calendar",select:"list",checkbox:"check",toggle:"settings",radio:"circle",file:"paperclip",rating:"star"})[b]||"edit";return e.jsxs("div",{className:"nice-form-builder-ai","data-testid":o["data-testid"],children:[y&&k&&e.jsxs("div",{className:"nice-form-builder-ai__toolbar",children:[e.jsxs("div",{className:"nice-form-builder-ai__toolbar-left",children:[e.jsx("span",{className:"nice-form-builder-ai__badge",children:"AI"}),O&&e.jsx("span",{className:"nice-form-builder-ai__loading",children:w("formBuilderAI.generating","Generating...")})]}),e.jsxs("div",{className:"nice-form-builder-ai__toolbar-right",children:[i&&e.jsxs("button",{type:"button",className:"nice-form-builder-ai__btn",onClick:()=>T(!0),disabled:O,children:[e.jsx(c.NiceIcon,{name:"zap",size:"sm"})," ",w("formBuilderAI.generateForm","Generate Form")]}),e.jsxs("div",{className:"nice-form-builder-ai__templates-dropdown",children:[e.jsxs("button",{type:"button",className:"nice-form-builder-ai__btn nice-form-builder-ai__btn--secondary",onClick:()=>K(!P),children:[e.jsx(c.NiceIcon,{name:"list",size:"sm"})," ",w("formBuilderAI.templates","Templates")," ",e.jsx(c.NiceIcon,{name:"chevron-down",size:"sm"})]}),P&&e.jsx("div",{className:"nice-form-builder-ai__templates-menu",children:h.map((b,F)=>e.jsxs("button",{type:"button",className:"nice-form-builder-ai__template-item",onClick:()=>x(b),children:[e.jsx("span",{className:"nice-form-builder-ai__template-name",children:b.name}),e.jsx("span",{className:"nice-form-builder-ai__template-desc",children:b.description})]},F))})]})]})]}),e.jsx("div",{className:"nice-form-builder-ai__builder-wrapper",children:e.jsx(X,{fields:E,value:C,onChange:N,columns:1})}),f&&e.jsxs("div",{className:"nice-form-builder-ai__panel",children:[e.jsx("div",{className:"nice-form-builder-ai__panel-overlay",onClick:()=>T(!1)}),e.jsxs("div",{className:"nice-form-builder-ai__panel-content",children:[e.jsxs("div",{className:"nice-form-builder-ai__panel-header",children:[e.jsxs("h4",{children:[e.jsx(c.NiceIcon,{name:"zap",size:"sm"})," ",w("formBuilderAI.generateFormTitle","Generate Form with AI")]}),e.jsx("button",{type:"button",className:"nice-form-builder-ai__panel-close",onClick:()=>{T(!1),I([]),D("")},"aria-label":"Close",children:e.jsx(c.NiceIcon,{name:"close",size:"sm"})})]}),e.jsxs("div",{className:"nice-form-builder-ai__panel-body",children:[e.jsxs("div",{className:"nice-form-builder-ai__prompt-section",children:[e.jsx("label",{className:"nice-form-builder-ai__label",children:w("formBuilderAI.describeForm","Describe the form you want to create:")}),e.jsx("textarea",{className:"nice-form-builder-ai__textarea",placeholder:w("formBuilderAI.promptPlaceholder",'e.g., "A contact form with name, email, phone, subject dropdown, and message textarea"'),value:$,onChange:b=>D(b.target.value),rows:3}),e.jsx("button",{type:"button",className:"nice-form-builder-ai__generate-btn",onClick:()=>J($),disabled:O||!$.trim(),children:O?w("formBuilderAI.generating","Generating..."):w("formBuilderAI.generate","Generate")})]}),M.length>0&&e.jsxs("div",{className:"nice-form-builder-ai__preview-section",children:[e.jsxs("h5",{children:[w("formBuilderAI.preview","Preview")," (",M.length," ",w("formBuilderAI.fields","fields"),")"]}),e.jsx("div",{className:"nice-form-builder-ai__fields-preview",children:M.map((b,F)=>e.jsxs("div",{className:"nice-form-builder-ai__field-preview",children:[e.jsx("span",{className:"nice-form-builder-ai__field-icon",children:e.jsx(c.NiceIcon,{name:j(b.type),size:"sm"})}),e.jsxs("div",{className:"nice-form-builder-ai__field-info",children:[e.jsxs("span",{className:"nice-form-builder-ai__field-label",children:[b.label,b.required&&e.jsx("span",{className:"nice-form-builder-ai__required",children:"*"})]}),e.jsx("span",{className:"nice-form-builder-ai__field-type",children:b.type})]}),b.options&&e.jsxs("span",{className:"nice-form-builder-ai__field-options",children:[b.options.length," options"]})]},F))})]})]}),e.jsxs("div",{className:"nice-form-builder-ai__panel-footer",children:[e.jsxs("button",{type:"button",className:"nice-form-builder-ai__apply-btn",onClick:()=>_(M),disabled:M.length===0||O,children:[e.jsx(c.NiceIcon,{name:"check",size:"sm"})," ",w("formBuilderAI.addToForm","Add to Form")]}),e.jsx("button",{type:"button",className:"nice-form-builder-ai__cancel-btn",onClick:()=>{T(!1),I([]),D("")},children:w("formBuilderAI.cancel","Cancel")})]})]})]})]})}),Pe={text:{type:"string"},textarea:{type:"string"},password:{type:"string",format:"password"},phone:{type:"string",format:"phone"},url:{type:"string",format:"uri"},email:{type:"string",format:"email"},date:{type:"string",format:"date"},datetime:{type:"string",format:"date-time"},time:{type:"string",format:"time"},color:{type:"string",format:"color"},number:{type:"number"},slider:{type:"number"},rating:{type:"integer"},checkbox:{type:"boolean"},toggle:{type:"boolean"},select:{type:"string"},radio:{type:"string"},multiselect:{type:"array",items:{type:"string"}},file:{type:"string",format:"data-url"},signature:{type:"string",format:"data-url"},richtext:{type:"string"},markdown:{type:"string"},code:{type:"string"},image:{type:"string",format:"uri"}};function ze(t,o){if(o)for(const a of o)switch(a.type){case"minLength":typeof a.value=="number"&&(t.minLength=a.value);break;case"maxLength":typeof a.value=="number"&&(t.maxLength=a.value);break;case"min":typeof a.value=="number"&&(t.minimum=a.value);break;case"max":typeof a.value=="number"&&(t.maximum=a.value);break;case"pattern":typeof a.value=="string"&&(t.pattern=a.value);break;case"email":t.format="email";break;case"url":t.format="uri";break}}function Je(t){if(t.type==="heading"||t.type==="paragraph"||t.type==="divider"||t.type==="spacer")return null;const o=Pe[t.type];if(!o)return null;const a={...o};return t.label&&(a.title=t.label),t.helpText&&(a.description=t.helpText),t.defaultValue!==void 0&&(a.default=t.defaultValue),t.options&&(t.type==="select"||t.type==="radio")&&(a.enum=t.options.map(r=>typeof r=="string"?r:r.value)),t.options&&t.type==="multiselect"&&(a.items={type:"string",enum:t.options.map(r=>typeof r=="string"?r:String(r.value))}),ze(a,t.validations),a}function Ue(t){const o={},a=[],r=i=>{var n;for(const d of i){if(d.type==="section"&&d.children){r(d.children);continue}const y=Je(d);y&&(o[d.name]=y,(d.required||(n=d.validations)!=null&&n.some(h=>h.type==="required"))&&a.push(d.name))}};for(const i of t.sections)r(i.fields);const s={$schema:"http://json-schema.org/draft-07/schema#",$id:t.id,type:"object",title:t.title,description:t.description,properties:o,additionalProperties:!1};return a.length>0&&(s.required=a),s}const He=[{target:".nice-manifest-editor",titleKey:"tutorial.manifestEditor.intro.title",title:"Manifest editor",contentKey:"tutorial.manifestEditor.intro.content",content:"Edit the manifest in schema-driven sections. Toggle Form ⇄ JSON per section; validation appears in the status bar.",placement:"auto"},{target:".nice-manifest-editor__pane",titleKey:"tutorial.manifestEditor.sections.title",title:"Sections",contentKey:"tutorial.manifestEditor.sections.content",content:"The manifest is split into schema-driven sections — switch between them using the tabs at the top.",placement:"auto"},{target:".nice-manifest-editor__pane",titleKey:"tutorial.manifestEditor.json.title",title:"Form ⇄ JSON",contentKey:"tutorial.manifestEditor.json.content",content:"Each section can be edited as a visual form or as raw JSON — use the toggle inside the section.",placement:"auto"}];function Ge(t){return t}const We=u.forwardRef(function(o,a){var F;const{value:r,defaultValue:s,sections:i,onChange:n,jsonView:d=!0,scriptRunner:y,triggers:h,bindings:g=[],handlers:l,onBindingsChange:f,revisions:T,onRollback:$,loadContent:D,logs:M,onClearLogs:I,extraTabs:E,validate:A,theme:P="light",height:K=560,tutorial:C,className:N,style:w,id:V,"data-testid":z}=o,{t:O}=c.useNiceTranslation(),[k,J]=c.useControllableState({value:r,defaultValue:s,fallbackValue:{},onChange:n,componentName:"NiceManifestEditor"}),_=u.useMemo(()=>{const q=i.map(U=>({key:`section:${U.id}`,label:U.title,icon:U.icon,content:e.jsx("div",{className:"nice-manifest-editor__pane",children:e.jsx(X,{schema:U.schema,fields:U.fields,uiSchema:U.uiSchema,value:k,onChange:J,showJsonView:d})})}));return y&&q.push({key:"scripts",label:O("manifestEditor.tab.scripts","Scripts"),content:e.jsx("div",{className:"nice-manifest-editor__pane",children:e.jsx(c.NiceScriptRunner,{...y})})}),h&&h.length>0&&q.push({key:"lifecycle",label:O("manifestEditor.tab.lifecycle","Lifecycle"),content:e.jsx("div",{className:"nice-manifest-editor__pane",children:e.jsx(c.NiceLifecycleHooksEditor,{triggers:h,bindings:g,handlers:l,onChange:U=>f==null?void 0:f(U),groupByTrigger:!0,allowCondition:!0})})}),T&&T.length>0&&q.push({key:"history",label:O("manifestEditor.tab.history","History"),content:e.jsx("div",{className:"nice-manifest-editor__pane",children:e.jsx(c.NiceRevisionHistory,{revisions:T,onRollback:$,loadContent:D,language:"json"})})}),E&&q.push(...E),q},[i,k,J,d,y,h,g,l,f,T,$,D,E,O]),[R,p]=u.useState(((F=_[0])==null?void 0:F.key)??"");u.useEffect(()=>{_.length>0&&!_.some(q=>q.key===R)&&p(_[0].key)},[_,R]);const x=u.useMemo(()=>A?A(k):[],[A,k]),j=u.useMemo(()=>{const q=[{key:"sections",label:`${i.length} ${O("manifestEditor.sections","sections")}`,position:"left"}];return A&&q.push({key:"validation",label:e.jsxs("span",{className:"nice-manifest-editor__status",children:[e.jsx(c.NiceIcon,{name:x.length===0?"check":"warning",size:12}),x.length===0?O("manifestEditor.status.valid","Valid"):`${x.length} ${O("manifestEditor.status.issues","issues")}`]}),position:"left"}),q},[i.length,A,x.length,O]),b="nice-manifest-editor"+(N?` ${N}`:"");return e.jsx(c.NiceConsole,{ref:a,id:V,className:b,style:{height:K,...w},"data-testid":z,theme:P,tabs:_,activeTabKey:R,onTabChange:p,statusItems:j,toolbar:C?e.jsx(c.NiceTutorialButton,{steps:c.resolveTutorial(C,He)}):void 0,bottomPanel:M!==void 0?e.jsx(c.NiceLogConsole,{title:O("manifestEditor.output","Output"),entries:M,onClear:I,maxHeight:"100%"}):void 0})}),te="__eeRid",ie="__eeFid",Ye=[{target:".nice-entity-editor",titleKey:"tutorial.entityEditor.intro.title",title:"Entity editor",contentKey:"tutorial.entityEditor.intro.content",content:"Browse your entities in the list, then click one (or “New entity”) to edit its metadata, fields and validation on a dedicated screen.",placement:"auto"}],Qe={type:"object",properties:{name:{type:"string",title:"Name",minLength:1,description:"Unique technical name of the entity (PascalCase)."},displayName:{type:"string",title:"Display name",description:"Human-friendly name shown in the UI."},tableName:{type:"string",title:"Table name",description:"Database table that backs this entity."},description:{type:"string",title:"Description",description:"Optional notes about the entity's purpose."},entityIcon:{type:"string",title:"Icon",description:"Icon key shown next to the entity."},isAudited:{type:"boolean",title:"Audited",description:"Track who created/changed each record and when."},isSoftDeleteEnabled:{type:"boolean",title:"Soft delete",description:"Flag rows as deleted instead of physically removing them."}},required:["name"]},Xe={type:"object",properties:{name:{type:"string",title:"Name",minLength:1,description:"Field's technical name (the database column)."},displayName:{type:"string",title:"Display name",description:"Human-friendly label shown in the UI."},dataType:{type:"string",title:"Type",description:"Storage / data type of the field.",enum:["Guid","string","text","int","long","decimal","double","bool","DateTime","DateOnly","json"]},isPrimaryKey:{type:"boolean",title:"Primary key",description:"Primary key — uniquely identifies each record."},isForeignKey:{type:"boolean",title:"Foreign key",description:"Foreign key — references another entity's primary key."},isRequired:{type:"boolean",title:"Required",description:"Value must be provided (NOT NULL)."},isUnique:{type:"boolean",title:"Unique",description:"Each value must be unique across all records."},isIndexed:{type:"boolean",title:"Indexed",description:"Add a database index for faster lookups and filtering."},isNullable:{type:"boolean",title:"Nullable",description:"Allow empty (NULL) values."},maxLength:{type:"integer",title:"Max length",description:"Maximum number of characters (for string types)."},defaultValue:{type:"string",title:"Default",description:"Value used when none is provided."},description:{type:"string",title:"Description",description:"Optional notes about the field."},isComputed:{type:"boolean",title:"Computed",description:"Value is derived from an expression instead of stored input."},computedExpression:{type:"string",title:"Computed expression",description:"Expression used to compute the value (when Computed is on)."}},required:["name","dataType"]};function ne({title:t,help:o}){return e.jsxs("span",{className:"nice-entity-editor__field-label",children:[t,o?e.jsx(c.NiceTooltip,{content:o,children:e.jsx("span",{className:"nice-entity-editor__help",role:"img","aria-label":o,children:e.jsx(c.NiceIcon,{name:"info",size:14})})}):null]})}function Ze({schema:t,value:o,onChange:a,readOnly:r}){const s=t.properties??{};return e.jsx("div",{className:"nice-entity-editor__field-form",children:Object.entries(s).map(([i,n])=>{const d=o[i],y=n.description,h=n.title??i;if(n.type==="boolean")return e.jsx("div",{className:"nice-entity-editor__field-row nice-entity-editor__field-row--check",children:e.jsx(c.NiceCheckbox,{label:e.jsx(ne,{title:h,help:y}),checked:!!d,onChange:l=>a(i,l),disabled:r})},i);if(Array.isArray(n.enum)&&n.enum.length>0)return e.jsxs("div",{className:"nice-entity-editor__field-row",children:[e.jsx(ne,{title:h,help:y}),e.jsx(c.NiceSelect,{options:n.enum.map(l=>({label:String(l),value:String(l)})),value:d==null?"":String(d),onChange:l=>a(i,l),clearable:!0,disabled:r})]},i);const g=n.type==="integer"||n.type==="number";return e.jsxs("div",{className:"nice-entity-editor__field-row",children:[e.jsx(ne,{title:h,help:y}),e.jsx(c.NiceTextInput,{value:d==null?"":String(d),onChange:l=>a(i,g?l===""?void 0:Number(l):l),disabled:r})]},i)})})}function et({fields:t,onChange:o,fieldSchema:a,readOnly:r}){const{t:s}=c.useNiceTranslation(),[i,n]=u.useState(null),d=u.useMemo(()=>t.map((l,f)=>({...l,[ie]:String(f)})),[t]),y=u.useMemo(()=>[{field:"name",header:s("entityEditor.field.name","Name"),sortable:!0,render:l=>e.jsx("span",{className:"nice-entity-editor__name",children:String(l??"")})},{field:"dataType",header:s("entityEditor.field.type","Type"),sortable:!0,render:l=>e.jsx(c.NiceBadge,{variant:"secondary",size:"sm",outline:!0,children:String(l??"—")})},{field:"__flags",header:s("entityEditor.field.flags","Constraints"),headerTooltip:s("entityEditor.field.flags.help","Key / required / unique / indexed constraints on this field"),render:(l,f)=>{const T=[[!!(f!=null&&f.isPrimaryKey),"PK",s("entityEditor.flag.pk","Primary key"),"info"],[!!(f!=null&&f.isForeignKey),"FK",s("entityEditor.flag.fk","Foreign key"),"info"],[!!(f!=null&&f.isRequired),"Req",s("entityEditor.flag.required","Required (NOT NULL)"),"warning"],[!!(f!=null&&f.isUnique),"Uniq",s("entityEditor.flag.unique","Unique"),"secondary"],[!!(f!=null&&f.isIndexed),"Idx",s("entityEditor.flag.indexed","Indexed"),"secondary"]];return e.jsx("span",{className:"nice-entity-editor__flags",children:T.filter(([$])=>$).map(([,$,D,M])=>e.jsx(c.NiceTooltip,{content:D,children:e.jsx(c.NiceBadge,{variant:M,size:"sm",children:$})},$))})}}],[]),h=(l,f,T)=>{o(t.map(($,D)=>D===l?{...$,[f]:T}:$))},g=()=>{const l=[...t,{name:`field${t.length+1}`,dataType:"string"}];o(l),n(l.length-1)};if(i!=null&&t[i]){const l=t[i];return e.jsxs("div",{className:"nice-entity-editor__field-detail",children:[e.jsxs("header",{className:"nice-entity-editor__edit-header",children:[e.jsx(c.NiceTooltip,{content:s("entityEditor.field.backHint","Back to the field list"),children:e.jsx(c.NiceButton,{variant:"ghost",size:"sm",leftIcon:e.jsx(c.NiceIcon,{name:"arrow-left",size:14}),onClick:()=>n(null),children:s("entityEditor.field.back","Fields")})}),e.jsx("span",{className:"nice-entity-editor__breadcrumb-sep",children:"/"}),e.jsx("span",{className:"nice-entity-editor__edit-title",children:String(l.name??s("entityEditor.field.untitled","New field"))})]}),e.jsx(Ze,{schema:a,value:l,onChange:(f,T)=>h(i,f,T),readOnly:r}),e.jsx("div",{className:"nice-entity-editor__field-detail-actions",children:e.jsx(c.NiceButton,{variant:"primary",size:"sm",onClick:()=>n(null),children:s("entityEditor.field.done","Done")})})]})}return e.jsx(c.NiceDataGrid,{data:d,keyField:ie,columns:y,searchable:!0,searchPlaceholder:s("entityEditor.field.search","Search fields…"),emptyText:s("entityEditor.field.empty","No fields yet. Add one to define this entity."),onRowClick:l=>n(Number(l[ie])),onRowDelete:r?void 0:l=>o(t.filter((f,T)=>T!==Number(l))),toolbar:r?void 0:e.jsx(c.NiceButton,{variant:"primary",size:"sm",leftIcon:e.jsx(c.NiceIcon,{name:"plus",size:14}),onClick:g,children:s("entityEditor.field.add","Add field")}),compact:!0,striped:!0})}const pe=u.forwardRef(function(o,a){const{value:r,defaultValue:s,onChange:i,entityMetaSchema:n=Qe,fieldSchema:d=Xe,fieldsKey:y="fields",validationsKey:h="validations",nameKey:g="name",renderErPreview:l,readOnly:f=!1,tutorial:T,className:$,style:D,id:M,"data-testid":I}=o,{t:E}=c.useNiceTranslation(),[A,P]=c.useControllableState({value:r,defaultValue:s,fallbackValue:[],onChange:i,componentName:"NiceEntityEditor"}),[K,C]=u.useState("list"),[N,w]=u.useState(0),[V,z]=u.useState("general"),O=Math.min(N,Math.max(0,A.length-1)),k=A[O],J=K==="edit"&&k!=null,_=u.useMemo(()=>{const S=k==null?void 0:k[y];return Array.isArray(S)?S:[]},[k,y]),R=u.useMemo(()=>{const S=B=>{const G=B.toLowerCase();return/(int|long|decimal|double|float|number|money)/.test(G)?"number":/bool/.test(G)?"boolean":/date|time/.test(G)?"date":"string"},L=[];for(const B of _){const G=String(B.name??"");G&&L.push({field:G,label:String(B.displayName??G),type:S(String(B.dataType??"string"))})}return L},[_]),p=u.useMemo(()=>{const S=k==null?void 0:k[h];return Array.isArray(S)?S:[]},[k,h]),x=u.useMemo(()=>A.map((S,L)=>({...S,[te]:String(L)})),[A]),j=S=>{P(A.map((L,B)=>B===O?{...L,...S}:L))},b=S=>{j({[y]:S})},F=S=>{w(S),z("general"),C("edit")},q=()=>{const S=[...A,{[g]:`Entity${A.length+1}`,[y]:[]}];P(S),w(S.length-1),z("general"),C("edit")},U=S=>{P(A.filter((L,B)=>B!==S)),w(L=>L>=S?Math.max(0,L-1):L)},Z=u.useMemo(()=>[{field:g,header:E("entityEditor.col.name","Name"),sortable:!0,render:S=>e.jsx("span",{className:"nice-entity-editor__name",children:String(S??"")})},{field:"displayName",header:E("entityEditor.col.displayName","Display name"),sortable:!0,render:S=>e.jsx("span",{className:"nice-entity-editor__muted",children:String(S??"—")})},{field:"tableName",header:E("entityEditor.col.table","Table"),sortable:!0,render:S=>e.jsx("span",{className:"nice-entity-editor__muted",children:String(S??"—")})},{field:y,header:E("entityEditor.col.fields","Fields"),align:"center",headerTooltip:E("entityEditor.col.fields.help","Number of fields defined on this entity"),render:S=>e.jsx(c.NiceBadge,{variant:"secondary",size:"sm",children:Array.isArray(S)?S.length:0})},{field:"__flags",header:E("entityEditor.col.flags","Flags"),render:(S,L)=>e.jsxs("span",{className:"nice-entity-editor__flags",children:[L!=null&&L.isAudited?e.jsx(c.NiceTooltip,{content:E("entityEditor.flag.audited","Audited — tracks who changed each record and when"),children:e.jsx(c.NiceBadge,{variant:"info",size:"sm",outline:!0,children:E("entityEditor.flag.audited.abbr","Audit")})}):null,L!=null&&L.isSoftDeleteEnabled?e.jsx(c.NiceTooltip,{content:E("entityEditor.flag.softDelete","Soft delete — rows are flagged deleted, never physically removed"),children:e.jsx(c.NiceBadge,{variant:"secondary",size:"sm",outline:!0,children:E("entityEditor.flag.softDelete.abbr","Soft-del")})}):null]})}],[g,y]),H=u.useMemo(()=>{const S=[{id:"general",label:E("entityEditor.tab.general","General"),content:k?e.jsx(X,{schema:n,value:k,onChange:L=>j(L),columns:2,readOnly:f,liveValidation:!0}):null},{id:"fields",label:E("entityEditor.tab.fields","Fields"),badge:_.length||void 0,content:e.jsx(et,{fields:_,onChange:b,fieldSchema:d,readOnly:f})},{id:"validation",label:E("entityEditor.tab.validation","Validation"),badge:p.length||void 0,content:e.jsx(c.NiceValidationBuilder,{fields:R,value:p,onChange:L=>j({[h]:L})})}];return l&&S.push({id:"er",label:E("entityEditor.tab.er","ER diagram"),content:e.jsx("div",{className:"nice-entity-editor__er",children:l(A)})}),S},[k,_,p,R,n,d,f,l,A]),Y="nice-entity-editor"+($?` ${$}`:"");return e.jsxs("div",{ref:a,id:M,className:Y,style:D,"data-testid":I,children:[T&&e.jsx("div",{className:"nice-entity-editor__tutorial",children:e.jsx(c.NiceTutorialButton,{steps:c.resolveTutorial(T,Ye)})}),J?e.jsxs("div",{className:"nice-entity-editor__edit",children:[e.jsxs("header",{className:"nice-entity-editor__edit-header",children:[e.jsx(c.NiceTooltip,{content:E("entityEditor.backHint","Back to the entity list"),children:e.jsx(c.NiceButton,{variant:"ghost",size:"sm",leftIcon:e.jsx(c.NiceIcon,{name:"arrow-left",size:14}),onClick:()=>C("list"),children:E("entityEditor.back","Entities")})}),e.jsx("span",{className:"nice-entity-editor__breadcrumb-sep",children:"/"}),e.jsx("span",{className:"nice-entity-editor__edit-title",children:String((k==null?void 0:k[g])??E("entityEditor.untitled","Untitled entity"))}),!f&&e.jsx(c.NiceTooltip,{content:E("entityEditor.deleteHint","Delete this entity"),children:e.jsx(c.NiceButton,{variant:"ghost",size:"sm",leftIcon:e.jsx(c.NiceIcon,{name:"trash",size:14}),onClick:()=>{U(O),C("list")},children:E("entityEditor.delete","Delete")})})]}),e.jsx(c.NiceTabs,{tabs:H,activeTab:V,onChange:z,variant:"enclosed"})]}):e.jsx("div",{className:"nice-entity-editor__list-view",children:e.jsx(c.NiceDataGrid,{data:x,keyField:te,columns:Z,searchable:!0,searchPlaceholder:E("entityEditor.search","Search entities…"),emptyText:E("entityEditor.empty","No entities yet. Create one to get started."),onRowClick:S=>F(Number(S[te])),onRowDelete:f?void 0:S=>U(Number(S)),toolbar:f?void 0:e.jsx(c.NiceButton,{variant:"primary",size:"sm",leftIcon:e.jsx(c.NiceIcon,{name:"plus",size:14}),onClick:q,children:E("entityEditor.new","New entity")}),compact:!0,striped:!0})})]})}),tt=[{target:".nice-i18n-editor",titleKey:"tutorial.i18nEditor.intro.title",title:"Translations",contentKey:"tutorial.i18nEditor.intro.content",content:"Edit translations as a keys × locales grid. Add keys and locales; amber cells mark missing translations.",placement:"auto"},{target:'[data-tour="i18n-grid"]',titleKey:"tutorial.i18nEditor.grid.title",title:"Keys × locales",contentKey:"tutorial.i18nEditor.grid.content",content:"Each row is a translation key and each column a locale. Edit a cell to set a translation; amber cells are still missing.",placement:"top"},{target:'[data-tour="i18n-add"]',titleKey:"tutorial.i18nEditor.add.title",title:"Add keys & locales",contentKey:"tutorial.i18nEditor.add.content",content:"Add a new translation key or a new locale column here; new cells start empty and are flagged as missing.",placement:"top"}],he=u.forwardRef(function(o,a){const{value:r,defaultValue:s,onChange:i,locales:n,allowEditLocales:d=!0,allowEditKeys:y=!0,highlightMissing:h=!0,readOnly:g=!1,tutorial:l,className:f,style:T,id:$,"data-testid":D}=o,{t:M}=W.useNiceTranslation(),[I,E]=W.useControllableState({value:r,defaultValue:s,fallbackValue:{},onChange:i,componentName:"NiceI18nEditor"}),[A,P]=u.useState(""),[K,C]=u.useState(""),N=u.useMemo(()=>n??Object.keys(I),[n,I]),w=u.useMemo(()=>{const p=new Set;for(const x of Object.keys(I))for(const j of Object.keys(I[x]??{}))p.add(j);return[...p].sort()},[I]),V=(p,x,j)=>{E({...I,[p]:{...I[p]??{},[x]:j}})},z=(p,x)=>{if(!x||x===p)return;const j={};for(const b of Object.keys(I)){const F={...I[b]??{}};p in F&&(F[x]=F[p],delete F[p]),j[b]=F}E(j)},O=p=>{const x={};for(const j of Object.keys(I)){const b={...I[j]??{}};delete b[p],x[j]=b}E(x)},k=()=>{const p=A.trim();if(!p||w.includes(p))return;const x={};for(const j of N)x[j]={...I[j]??{},[p]:""};for(const j of Object.keys(I))x[j]||(x[j]=I[j]);E(x),P("")},J=()=>{const p=K.trim();if(!p||I[p])return;const x={};for(const j of w)x[j]="";E({...I,[p]:x}),C("")},_=p=>{const x={...I};delete x[p],E(x)},R="nice-i18n-editor"+(f?` ${f}`:"");return e.jsxs("div",{ref:a,id:$,className:R,style:T,"data-testid":D,children:[l&&e.jsx("div",{className:"nice-i18n-editor__tutorial",children:e.jsx(W.NiceTutorialButton,{steps:W.resolveTutorial(l,tt)})}),e.jsx("div",{className:"nice-i18n-editor__scroll","data-tour":"i18n-grid",children:e.jsxs("table",{className:"nice-i18n-editor__table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{className:"nice-i18n-editor__key-head",children:M("i18nEditor.keyHead","Key")}),N.map(p=>e.jsxs("th",{className:"nice-i18n-editor__locale-head",children:[e.jsx("span",{children:p}),d&&!g&&e.jsx("button",{type:"button",className:"nice-i18n-editor__locale-remove","aria-label":`${M("i18nEditor.removeLocale","Remove locale")} ${p}`,onClick:()=>_(p),children:e.jsx(W.NiceIcon,{name:"close",size:12})})]},p))]})}),e.jsxs("tbody",{children:[w.map(p=>e.jsxs("tr",{children:[e.jsxs("td",{className:"nice-i18n-editor__key-cell",children:[y&&!g?e.jsx("input",{className:"nice-i18n-editor__key-input",defaultValue:p,onBlur:x=>z(p,x.target.value.trim()),"aria-label":M("i18nEditor.keyAria","Translation key")}):e.jsx("span",{className:"nice-i18n-editor__key-text",children:p}),y&&!g&&e.jsx("button",{type:"button",className:"nice-i18n-editor__key-remove","aria-label":`${M("i18nEditor.removeKey","Remove key")} ${p}`,onClick:()=>O(p),children:e.jsx(W.NiceIcon,{name:"close",size:12})})]}),N.map(x=>{var F;const j=((F=I[x])==null?void 0:F[p])??"",b=h&&j==="";return e.jsx("td",{className:"nice-i18n-editor__cell",children:e.jsx("input",{className:"nice-i18n-editor__cell-input"+(b?" nice-i18n-editor__cell-input--missing":""),value:j,readOnly:g,onChange:q=>V(x,p,q.target.value),"aria-label":`${p} (${x})`})},x)})]},p)),w.length===0&&e.jsx("tr",{children:e.jsx("td",{className:"nice-i18n-editor__empty",colSpan:N.length+1,children:M("i18nEditor.empty","No translation keys yet.")})})]})]})}),!g&&(y||d)&&e.jsxs("div",{className:"nice-i18n-editor__toolbar","data-tour":"i18n-add",children:[y&&e.jsxs("div",{className:"nice-i18n-editor__add",children:[e.jsx("input",{className:"nice-i18n-editor__add-input",placeholder:M("i18nEditor.newKeyPlaceholder","new.key"),value:A,onChange:p=>P(p.target.value),onKeyDown:p=>{p.key==="Enter"&&k()},"aria-label":M("i18nEditor.newKeyAria","New key")}),e.jsxs("button",{type:"button",onClick:k,children:["+ ",M("i18nEditor.addKey","Key")]})]}),d&&e.jsxs("div",{className:"nice-i18n-editor__add",children:[e.jsx("input",{className:"nice-i18n-editor__add-input",placeholder:M("i18nEditor.newLocalePlaceholder","locale (e.g. de)"),value:K,onChange:p=>C(p.target.value),onKeyDown:p=>{p.key==="Enter"&&J()},"aria-label":M("i18nEditor.newLocaleAria","New locale")}),e.jsxs("button",{type:"button",onClick:J,children:["+ ",M("i18nEditor.addLocale","Locale")]})]})]})]})}),it=[{target:".nice-module-editor",titleKey:"tutorial.moduleEditor.intro.title",title:"Module editor",contentKey:"tutorial.moduleEditor.intro.content",content:"Design a whole module end-to-end — manifest, entities, translations, views, workflows, data sources and permissions — then validate and save.",placement:"auto"},{target:'[data-tour="nme-browser"]',titleKey:"tutorial.moduleEditor.browser.title",title:"Module browser",contentKey:"tutorial.moduleEditor.browser.content",content:"Search and pick a module here to open its manifest, entities and translations.",placement:"right"},{target:'[data-tour="nme-tabs"]',titleKey:"tutorial.moduleEditor.tabs.title",title:"Module parts",contentKey:"tutorial.moduleEditor.tabs.content",content:"Each tab edits one part of the module: Manifest sections, Entities, i18n, Views, Workflows, Data sources, Permissions and more.",placement:"bottom"},{target:'[data-tour="nme-validate"]',titleKey:"tutorial.moduleEditor.validate.title",title:"Validate",contentKey:"tutorial.moduleEditor.validate.content",content:"Check the module against the manifest schema. Issues appear in the status bar and the output panel.",placement:"bottom"},{target:'[data-tour="nme-save"]',titleKey:"tutorial.moduleEditor.save.title",title:"Save",contentKey:"tutorial.moduleEditor.save.content",content:"Persist your changes through the configured data provider (e.g. write the files back to disk).",placement:"bottom"},{target:'[data-tour="nme-output"]',titleKey:"tutorial.moduleEditor.output.title",title:"Output",contentKey:"tutorial.moduleEditor.output.content",content:"Validation results and load/save activity are logged here.",placement:"top"}],nt=u.forwardRef(function(o,a){var le;const{dataProvider:r,manifestSections:s,entityConfig:i,locales:n,validate:d,scriptRunner:y,triggers:h,bindings:g=[],handlers:l,onBindingsChange:f,revisions:T,onRollback:$,loadContent:D,theme:M="light",height:I=640,tutorial:E,className:A,style:P,id:K,"data-testid":C}=o,{t:N}=c.useNiceTranslation(),[w,V]=u.useState([]),[z,O]=u.useState(""),[k,J]=u.useState(null),[_,R]=u.useState(null),[p,x]=u.useState(!1),[j,b]=u.useState(!1),[F,q]=u.useState([]),[U,Z]=u.useState(""),H=u.useCallback((m,v,ke)=>{q(Se=>[...Se,{level:m,message:v,data:ke,timestamp:Date.now()}].slice(-200))},[]),Y=u.useCallback(async()=>{b(!0);try{V(await r.listModules())}catch(m){H("error",`List modules failed: ${m instanceof Error?m.message:String(m)}`)}finally{b(!1)}},[r,H]);u.useEffect(()=>{Y()},[Y]);const S=u.useCallback(async m=>{b(!0);try{const v=await r.loadModule(m);R(v),J(m),x(!1),H("info",`Loaded module ${m}`)}catch(v){H("error",`Load failed: ${v instanceof Error?v.message:String(v)}`)}finally{b(!1)}},[r,H]),L=u.useCallback(async()=>{if(!(!k||!_)){b(!0);try{await r.saveModule(k,_),x(!1),H("info",`Saved module ${k}`)}catch(m){H("error",`Save failed: ${m instanceof Error?m.message:String(m)}`)}finally{b(!1)}}},[k,_,r,H]),B=u.useMemo(()=>{if(!_)return[];const m=[];for(const v of s)v.schema&&m.push(...oe(_.manifest??{},v.schema));return d&&m.push(...d(_)),m},[_,s,d]),G=u.useCallback(()=>{if(B.length===0)H("info","Validation passed");else{H("warn",`${B.length} validation issue(s)`);for(const m of B)H("error",`${m.field}: ${m.message}`)}},[B,H]),fe=m=>{R(v=>v&&{...v,manifest:m}),x(!0)},ye=m=>{R(v=>v&&{...v,entities:m}),x(!0)},ge=m=>{R(v=>v&&{...v,i18n:m}),x(!0)},be=m=>{R(v=>v&&{...v,views:m}),x(!0)},ve=m=>{R(v=>v&&{...v,workflows:m}),x(!0)},Ne=m=>{R(v=>v&&{...v,dataSources:m}),x(!0)},xe=m=>{R(v=>v&&{...v,rbac:m}),x(!0)},Q=u.useMemo(()=>{if(!_)return[];const m=s.map(v=>({key:`section:${v.id}`,label:v.title,icon:v.icon,content:e.jsx("div",{className:"nice-module-editor__pane",children:e.jsx(X,{schema:v.schema,fields:v.fields,uiSchema:v.uiSchema,value:_.manifest??{},onChange:fe,showJsonView:!0})})}));return m.push({key:"entities",label:N("moduleEditor.tab.entities","Entities"),content:e.jsx("div",{className:"nice-module-editor__pane",children:e.jsx(pe,{value:_.entities??[],onChange:ye,entityMetaSchema:i==null?void 0:i.entityMetaSchema,fieldSchema:i==null?void 0:i.fieldSchema,fieldsKey:i==null?void 0:i.fieldsKey,nameKey:i==null?void 0:i.nameKey,renderErPreview:i==null?void 0:i.renderErPreview})})}),m.push({key:"i18n",label:N("moduleEditor.tab.i18n","i18n"),content:e.jsx("div",{className:"nice-module-editor__pane",children:e.jsx(he,{value:_.i18n??{},onChange:ge,locales:n})})}),m.push({key:"views",label:N("moduleEditor.tab.views","Views"),content:e.jsx("div",{className:"nice-module-editor__pane",children:e.jsx(at,{views:_.views??[],entities:_.entities??[],onChange:be})})}),m.push({key:"workflows",label:N("moduleEditor.tab.workflows","Workflows"),content:e.jsx("div",{className:"nice-module-editor__pane",children:e.jsx(st,{workflows:_.workflows??[],onChange:ve})})}),m.push({key:"data",label:N("moduleEditor.tab.data","Data"),content:e.jsx("div",{className:"nice-module-editor__pane",children:e.jsx(lt,{dataSources:_.dataSources??[],schemas:ot(_.entities??[]),onChange:Ne})})}),m.push({key:"permissions",label:N("moduleEditor.tab.permissions","Permissions"),content:e.jsx("div",{className:"nice-module-editor__pane",children:e.jsx(c.NiceAccessManager,{value:_.rbac??rt(_),onChange:xe})})}),y&&m.push({key:"scripts",label:N("moduleEditor.tab.scripts","Scripts"),content:e.jsx("div",{className:"nice-module-editor__pane",children:e.jsx(c.NiceScriptRunner,{...y})})}),h&&h.length>0&&m.push({key:"lifecycle",label:N("moduleEditor.tab.lifecycle","Lifecycle"),content:e.jsx("div",{className:"nice-module-editor__pane",children:e.jsx(c.NiceLifecycleHooksEditor,{triggers:h,bindings:g,handlers:l,onChange:v=>f==null?void 0:f(v),groupByTrigger:!0,allowCondition:!0})})}),T&&T.length>0&&m.push({key:"history",label:N("moduleEditor.tab.history","History"),content:e.jsx("div",{className:"nice-module-editor__pane",children:e.jsx(c.NiceRevisionHistory,{revisions:T,onRollback:$,loadContent:D,language:"json"})})}),m.push({key:"source",label:N("moduleEditor.tab.source","Source"),content:e.jsx("div",{className:"nice-module-editor__pane",children:e.jsx("pre",{className:"nice-module-editor__source",children:JSON.stringify(_,null,2)})})}),m},[_,s,i,n,y,h,g,l,T,N]);u.useEffect(()=>{Q.length>0&&!Q.some(m=>m.key===U)&&Z(Q[0].key)},[Q,U]);const re=u.useMemo(()=>{const m=z.trim().toLowerCase();return m?w.filter(v=>v.id.toLowerCase().includes(m)||(v.name??"").toLowerCase().includes(m)||(v.category??"").toLowerCase().includes(m)):w},[w,z]),_e=u.useMemo(()=>{const m=[];return k&&m.push({key:"mod",label:k+(p?" •":""),position:"left"}),m.push({key:"val",label:e.jsxs("span",{className:"nice-module-editor__status",children:[e.jsx(c.NiceIcon,{name:B.length===0?"check":"warning",size:12}),B.length===0?N("moduleEditor.status.valid","Valid"):`${B.length} ${N("moduleEditor.status.issues","issues")}`]}),position:"left"}),m},[k,p,B.length,N]),je=e.jsxs("div",{className:"nice-module-editor__browser","data-tour":"nme-browser",children:[e.jsx("input",{className:"nice-module-editor__search",placeholder:N("moduleEditor.searchModules","Search modules…"),value:z,onChange:m=>O(m.target.value),"aria-label":N("moduleEditor.searchModules","Search modules…")}),e.jsxs("div",{className:"nice-module-editor__modules",children:[re.map(m=>e.jsxs("button",{type:"button",className:"nice-module-editor__module"+(m.id===k?" nice-module-editor__module--active":""),onClick:()=>void S(m.id),title:m.description,children:[e.jsx("span",{className:"nice-module-editor__module-name",children:m.name??m.id}),m.category&&e.jsx("span",{className:"nice-module-editor__module-cat",children:m.category})]},m.id)),re.length===0&&e.jsx("div",{className:"nice-module-editor__browser-empty",children:j?N("moduleEditor.loading","Loading…"):N("moduleEditor.noModules","No modules. Open a source first.")})]})]}),Ee=e.jsxs("div",{className:"nice-module-editor__toolbar",children:[e.jsx("strong",{className:"nice-module-editor__title","data-tour":"nme-tabs",children:k?((le=_==null?void 0:_.manifest)==null?void 0:le.packageName)??k:N("moduleEditor.title","Module Editor")}),E&&e.jsx(c.NiceTutorialButton,{steps:c.resolveTutorial(E,it)}),e.jsx("span",{className:"nice-module-editor__spacer"}),e.jsxs("button",{type:"button",onClick:()=>void Y(),disabled:j,children:[e.jsx(c.NiceIcon,{name:"refresh",size:14})," ",N("moduleEditor.refresh","Refresh")]}),e.jsxs("button",{type:"button","data-tour":"nme-validate",onClick:G,disabled:!_,children:[e.jsx(c.NiceIcon,{name:"check",size:14})," ",N("moduleEditor.validate","Validate")]}),e.jsx("button",{type:"button","data-tour":"nme-save",className:"nice-module-editor__save",onClick:()=>void L(),disabled:!_||!p||j,children:j?N("moduleEditor.saving","Saving…"):N("moduleEditor.save","Save")})]}),we="nice-module-editor"+(A?` ${A}`:"");return e.jsx(c.NiceConsole,{ref:a,id:K,className:we,style:{height:I,...P},"data-testid":C,theme:M,tabs:Q,activeTabKey:U,onTabChange:Z,toolbar:Ee,sidePanel:je,sidePanelWidth:260,statusItems:_e,bottomPanel:e.jsx("div",{"data-tour":"nme-output",style:{height:"100%"},children:e.jsx(c.NiceLogConsole,{title:N("moduleEditor.output","Output"),entries:F,onClear:()=>q([]),maxHeight:"100%"})}),children:!_&&e.jsx("div",{className:"nice-module-editor__placeholder",children:N("moduleEditor.placeholder","Select a module from the left to start editing.")})})});function at({views:t,entities:o,onChange:a}){var g;const{t:r}=c.useNiceTranslation(),[s,i]=u.useState(((g=t[0])==null?void 0:g.id)??null),n=t.find(l=>l.id===s)??null,d=l=>{a(t.map(f=>f.id===s?l:f)),l.id!==s&&i(l.id)},y=()=>{const l={id:`view-${Date.now().toString(36)}`,name:"New View",version:2,columns:12,rows:[],dataSources:[]};a([...t,l]),i(l.id)},h=l=>{a(t.filter(f=>f.id!==l)),s===l&&i(null)};return e.jsxs("div",{className:"nice-module-views",children:[e.jsxs("div",{className:"nice-module-views__bar",children:[e.jsxs("select",{className:"nice-module-views__select",value:s??"",onChange:l=>i(l.target.value||null),"aria-label":r("moduleEditor.views.select","Select view"),children:[e.jsx("option",{value:"",children:r("moduleEditor.views.placeholder","— select view —")}),t.map(l=>e.jsx("option",{value:l.id,children:l.name},l.id))]}),e.jsxs("button",{type:"button",onClick:y,children:["+ ",r("moduleEditor.views.new","New view")]}),n&&e.jsx("button",{type:"button",onClick:()=>h(n.id),children:r("moduleEditor.delete","Delete")})]}),n?e.jsx(c.NiceViewEditor,{value:n,onChange:d,entities:o,height:520}):e.jsx("div",{className:"nice-module-views__empty",children:r("moduleEditor.views.empty","No view selected. Create one, then use “New from entity” inside the editor.")})]})}function st({workflows:t,onChange:o}){var h;const{t:a}=c.useNiceTranslation(),[r,s]=u.useState(((h=t[0])==null?void 0:h.id)??null),i=t.find(g=>g.id===r)??null,n=g=>{o(t.map(l=>l.id===r?g:l)),g.id!==r&&s(g.id)},d=()=>{const g={id:`workflow-${Date.now().toString(36)}`,name:"New Workflow",entityType:"",version:1,states:[],transitions:[]};o([...t,g]),s(g.id)},y=g=>{o(t.filter(l=>l.id!==g)),r===g&&s(null)};return e.jsxs("div",{className:"nice-module-views",children:[e.jsxs("div",{className:"nice-module-views__bar",children:[e.jsxs("select",{className:"nice-module-views__select",value:r??"",onChange:g=>s(g.target.value||null),"aria-label":a("moduleEditor.workflows.select","Select workflow"),children:[e.jsx("option",{value:"",children:a("moduleEditor.workflows.placeholder","— select workflow —")}),t.map(g=>e.jsx("option",{value:g.id,children:g.name},g.id))]}),e.jsxs("button",{type:"button",onClick:d,children:["+ ",a("moduleEditor.workflows.new","New workflow")]}),i&&e.jsx("button",{type:"button",onClick:()=>y(i.id),children:a("moduleEditor.delete","Delete")})]}),i?e.jsx(c.NiceWorkflowDesigner,{workflow:i,onChange:n}):e.jsx("div",{className:"nice-module-views__empty",children:a("moduleEditor.workflows.empty","No workflow selected. Create one to start designing states and transitions.")})]})}function ot(t){return t.map(o=>{const a=o;return{name:String(a.tableName||a.name||"Entity"),columns:(Array.isArray(a.fields)?a.fields:[]).map(r=>({name:String(r.name??""),dataType:String(r.dataType??"string"),isPrimaryKey:!!r.isPrimaryKey,isForeignKey:!!r.isForeignKey}))}})}function rt(t){const o=t.manifest??{},a=String(o.displayName||o.packageName||"Module"),r=(t.views??[]).map(i=>({id:`view:${i.id}`,label:i.name,type:"view"})),s=(t.entities??[]).map(i=>{const n=String(i.name??"Entity");return{id:`entity:${n}`,label:n,type:"entity"}});return{roles:[{id:"admin",label:"Admin"},{id:"user",label:"User"}],actions:[{id:"view",label:"View"},{id:"create",label:"Create"},{id:"edit",label:"Edit"},{id:"delete",label:"Delete"}],resources:[{id:"module",label:a,type:"module",children:[...r.length?[{id:"views",label:"Views",type:"group",children:r}]:[],...s.length?[{id:"entities",label:"Entities",type:"group",children:s}]:[]]}],grants:{}}}function lt({dataSources:t,schemas:o,onChange:a}){var g;const{t:r}=c.useNiceTranslation(),[s,i]=u.useState(((g=t[0])==null?void 0:g.key)??null),n=t.find(l=>l.key===s)??null,d=l=>{a(t.map(f=>f.key===s?l:f)),l.key!==s&&i(l.key)},y=()=>{const l={key:`ds-${Date.now().toString(36)}`,kind:"query",query:{tables:[],joins:[],conditions:[],sorts:[],groupBy:[],distinct:!1},sql:""};a([...t,l]),i(l.key)},h=l=>{a(t.filter(f=>f.key!==l)),s===l&&i(null)};return e.jsxs("div",{className:"nice-module-views",children:[e.jsxs("div",{className:"nice-module-views__bar",children:[e.jsxs("select",{className:"nice-module-views__select",value:s??"",onChange:l=>i(l.target.value||null),"aria-label":r("moduleEditor.data.select","Select data source"),children:[e.jsx("option",{value:"",children:r("moduleEditor.data.placeholder","— select data source —")}),t.map(l=>e.jsx("option",{value:l.key,children:l.label||l.key},l.key))]}),e.jsxs("button",{type:"button",onClick:y,children:["+ ",r("moduleEditor.data.new","New data source")]}),n&&e.jsx("button",{type:"button",onClick:()=>h(n.key),children:r("moduleEditor.delete","Delete")})]}),n?e.jsx(c.NiceDataSourceBuilder,{value:n,onChange:d,schemas:o}):e.jsx("div",{className:"nice-module-views__empty",children:r("moduleEditor.data.empty","No data source selected. Create one to build a query from your module’s schema.")})]})}exports.NiceArrayField=me;exports.NiceEntityEditor=pe;exports.NiceFormBuilderAI=Be;exports.NiceI18nEditor=he;exports.NiceManifestEditor=We;exports.NiceModuleEditor=nt;exports.NiceSchemaForm=X;exports.defineManifestSection=Ge;exports.formBuilderSchemaToNiceFormItems=Fe;exports.formFieldsToFormItems=se;exports.formSchemaToJsonSchema=Ue;exports.jsonSchemaToFormItems=ae;exports.schemaToFormItems=Ie;exports.validateAgainstJsonSchema=oe;exports.validateFormSchema=Ce;