@nice2dev/ui-forms 1.3.11 → 1.3.12
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/README.md +8 -5
- package/dist/index.cjs +6 -5
- package/dist/index.d.ts +60 -9
- package/dist/index.mjs +4193 -3100
- package/dist/ui-forms.css +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),
|
|
2
|
-
`).length)),onChange:
|
|
3
|
-
`).length)),onChange:F=>{const H=F.target.value;V(H);try{const G=JSON.parse(H);J(null),h(G)}catch(G){J(G instanceof Error?G.message:b("schemaForm.invalidJson","Invalid JSON"))}}}),N&&e.jsx("div",{className:"nice-schema-form__json-error",children:N})]}):e.jsx(c.NiceForm,{items:X,data:E,onFieldChange:K,columns:p,labelPosition:v,readOnly:k}),w&&Q.length>0&&e.jsx("ul",{className:"nice-schema-form__errors",role:"alert",children:Q.map((F,H)=>e.jsx("li",{className:"nice-schema-form__error",children:F.message},`${F.field}-${H}`))})]})}),ke="__eeRid",je="__eeFid",lt=[{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"}],dt={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"]},rt={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:a}){return e.jsxs("span",{className:"nice-entity-editor__field-label",children:[t,a?e.jsx(c.NiceTooltip,{content:a,children:e.jsx("span",{className:"nice-entity-editor__help",role:"img","aria-label":a,children:e.jsx(c.NiceIcon,{name:"info",size:14})})}):null]})}function ct({schema:t,value:a,onChange:o,readOnly:r}){const u=t.properties??{};return e.jsx("div",{className:"nice-entity-editor__field-form",children:Object.entries(u).map(([i,s])=>{const l=a[i],n=s.description,m=s.title??i;if(s.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:m,help:n}),checked:!!l,onChange:p=>o(i,p),disabled:r})},i);if(Array.isArray(s.enum)&&s.enum.length>0)return e.jsxs("div",{className:"nice-entity-editor__field-row",children:[e.jsx(Ne,{title:m,help:n}),e.jsx(c.NiceSelect,{options:s.enum.map(p=>({label:String(p),value:String(p)})),value:l==null?"":String(l),onChange:p=>o(i,p),clearable:!0,disabled:r})]},i);const d=s.type==="integer"||s.type==="number";return e.jsxs("div",{className:"nice-entity-editor__field-row",children:[e.jsx(Ne,{title:m,help:n}),e.jsx(c.NiceTextInput,{value:l==null?"":String(l),onChange:p=>o(i,d?p===""?void 0:Number(p):p),disabled:r})]},i)})})}function ut({fields:t,onChange:a,fieldSchema:o,readOnly:r}){const{t:u}=c.useNiceTranslation(),[i,s]=g.useState(null),l=g.useMemo(()=>t.map((p,v)=>({...p,[je]:String(v)})),[t]),n=g.useMemo(()=>[{field:"name",header:u("entityEditor.field.name","Name"),sortable:!0,render:p=>e.jsx("span",{className:"nice-entity-editor__name",children:String(p??"")})},{field:"dataType",header:u("entityEditor.field.type","Type"),sortable:!0,render:p=>e.jsx(c.NiceBadge,{variant:"secondary",size:"sm",outline:!0,children:String(p??"—")})},{field:"__flags",header:u("entityEditor.field.flags","Constraints"),headerTooltip:u("entityEditor.field.flags.help","Key / required / unique / indexed constraints on this field"),render:(p,v)=>{const k=[[!!(v!=null&&v.isPrimaryKey),"PK",u("entityEditor.flag.pk","Primary key"),"info"],[!!(v!=null&&v.isForeignKey),"FK",u("entityEditor.flag.fk","Foreign key"),"info"],[!!(v!=null&&v.isRequired),"Req",u("entityEditor.flag.required","Required (NOT NULL)"),"warning"],[!!(v!=null&&v.isUnique),"Uniq",u("entityEditor.flag.unique","Unique"),"secondary"],[!!(v!=null&&v.isIndexed),"Idx",u("entityEditor.flag.indexed","Indexed"),"secondary"]];return e.jsx("span",{className:"nice-entity-editor__flags",children:k.filter(([w])=>w).map(([,w,A,R])=>e.jsx(c.NiceTooltip,{content:A,children:e.jsx(c.NiceBadge,{variant:R,size:"sm",children:w})},w))})}}],[]),m=(p,v,k)=>{a(t.map((w,A)=>A===p?{...w,[v]:k}:w))},d=()=>{const p=[...t,{name:`field${t.length+1}`,dataType:"string"}];a(p),s(p.length-1)};if(i!=null&&t[i]){const p=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:u("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:()=>s(null),children:u("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(p.name??u("entityEditor.field.untitled","New field"))})]}),e.jsx(ct,{schema:o,value:p,onChange:(v,k)=>m(i,v,k),readOnly:r}),e.jsx("div",{className:"nice-entity-editor__field-detail-actions",children:e.jsx(c.NiceButton,{variant:"primary",size:"sm",onClick:()=>s(null),children:u("entityEditor.field.done","Done")})})]})}return e.jsx(c.NiceDataGrid,{data:l,keyField:je,columns:n,searchable:!0,searchPlaceholder:u("entityEditor.field.search","Search fields…"),emptyText:u("entityEditor.field.empty","No fields yet. Add one to define this entity."),onRowClick:p=>s(Number(p[je])),onRowDelete:r?void 0:p=>a(t.filter((v,k)=>k!==Number(p))),toolbar:r?void 0:e.jsx(c.NiceButton,{variant:"primary",size:"sm",leftIcon:e.jsx(c.NiceIcon,{name:"plus",size:14}),onClick:d,children:u("entityEditor.field.add","Add field")}),compact:!0,striped:!0})}const Te=g.forwardRef(function(a,o){const{value:r,defaultValue:u,onChange:i,entityMetaSchema:s=dt,fieldSchema:l=rt,fieldsKey:n="fields",validationsKey:m="validations",nameKey:d="name",renderErPreview:p,readOnly:v=!1,tutorial:k,className:w,style:A,id:R,"data-testid":L}=a,{t:j}=c.useNiceTranslation(),[$,M]=c.useControllableState({value:r,defaultValue:u,fallbackValue:[],onChange:i,componentName:"NiceEntityEditor"}),[b,E]=g.useState("list"),[h,y]=g.useState(0),[S,O]=g.useState("general"),V=Math.min(h,Math.max(0,$.length-1)),N=$[V],J=b==="edit"&&N!=null,X=g.useMemo(()=>{const x=N==null?void 0:N[n];return Array.isArray(x)?x:[]},[N,n]),Q=g.useMemo(()=>{const x=B=>{const q=B.toLowerCase();return/(int|long|decimal|double|float|number|money)/.test(q)?"number":/bool/.test(q)?"boolean":/date|time/.test(q)?"date":"string"},C=[];for(const B of X){const q=String(B.name??"");q&&C.push({field:q,label:String(B.displayName??q),type:x(String(B.dataType??"string"))})}return C},[X]),K=g.useMemo(()=>{const x=N==null?void 0:N[m];return Array.isArray(x)?x:[]},[N,m]),T=g.useMemo(()=>$.map((x,C)=>({...x,[ke]:String(C)})),[$]),F=x=>{M($.map((C,B)=>B===V?{...C,...x}:C))},H=x=>{F({[n]:x})},G=x=>{y(x),O("general"),E("edit")},ee=()=>{const x=[...$,{[d]:`Entity${$.length+1}`,[n]:[]}];M(x),y(x.length-1),O("general"),E("edit")},te=x=>{M($.filter((C,B)=>B!==x)),y(C=>C>=x?Math.max(0,C-1):C)},ae=g.useMemo(()=>[{field:d,header:j("entityEditor.col.name","Name"),sortable:!0,render:x=>e.jsx("span",{className:"nice-entity-editor__name",children:String(x??"")})},{field:"displayName",header:j("entityEditor.col.displayName","Display name"),sortable:!0,render:x=>e.jsx("span",{className:"nice-entity-editor__muted",children:String(x??"—")})},{field:"tableName",header:j("entityEditor.col.table","Table"),sortable:!0,render:x=>e.jsx("span",{className:"nice-entity-editor__muted",children:String(x??"—")})},{field:n,header:j("entityEditor.col.fields","Fields"),align:"center",headerTooltip:j("entityEditor.col.fields.help","Number of fields defined on this entity"),render:x=>e.jsx(c.NiceBadge,{variant:"secondary",size:"sm",children:Array.isArray(x)?x.length:0})},{field:"__flags",header:j("entityEditor.col.flags","Flags"),render:(x,C)=>e.jsxs("span",{className:"nice-entity-editor__flags",children:[C!=null&&C.isAudited?e.jsx(c.NiceTooltip,{content:j("entityEditor.flag.audited","Audited — tracks who changed each record and when"),children:e.jsx(c.NiceBadge,{variant:"info",size:"sm",outline:!0,children:j("entityEditor.flag.audited.abbr","Audit")})}):null,C!=null&&C.isSoftDeleteEnabled?e.jsx(c.NiceTooltip,{content:j("entityEditor.flag.softDelete","Soft delete — rows are flagged deleted, never physically removed"),children:e.jsx(c.NiceBadge,{variant:"secondary",size:"sm",outline:!0,children:j("entityEditor.flag.softDelete.abbr","Soft-del")})}):null]})}],[d,n]),_=g.useMemo(()=>{const x=[{id:"general",label:j("entityEditor.tab.general","General"),content:N?e.jsx(pe,{schema:s,value:N,onChange:C=>F(C),columns:2,readOnly:v,liveValidation:!0}):null},{id:"fields",label:j("entityEditor.tab.fields","Fields"),badge:X.length||void 0,content:e.jsx(ut,{fields:X,onChange:H,fieldSchema:l,readOnly:v})},{id:"validation",label:j("entityEditor.tab.validation","Validation"),badge:K.length||void 0,content:e.jsx(c.NiceValidationBuilder,{fields:Q,value:K,onChange:C=>F({[m]:C})})}];return p&&x.push({id:"er",label:j("entityEditor.tab.er","ER diagram"),content:e.jsx("div",{className:"nice-entity-editor__er",children:p($)})}),x},[N,X,K,Q,s,l,v,p,$]),I="nice-entity-editor"+(w?` ${w}`:"");return e.jsxs("div",{ref:o,id:R,className:I,style:A,"data-testid":L,children:[k&&e.jsx("div",{className:"nice-entity-editor__tutorial",children:e.jsx(c.NiceTutorialButton,{steps:c.resolveTutorial(k,lt)})}),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:j("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:()=>E("list"),children:j("entityEditor.back","Entities")})}),e.jsx("span",{className:"nice-entity-editor__breadcrumb-sep",children:"/"}),e.jsx("span",{className:"nice-entity-editor__edit-title",children:String((N==null?void 0:N[d])??j("entityEditor.untitled","Untitled entity"))}),!v&&e.jsx(c.NiceTooltip,{content:j("entityEditor.deleteHint","Delete this entity"),children:e.jsx(c.NiceButton,{variant:"ghost",size:"sm",leftIcon:e.jsx(c.NiceIcon,{name:"trash",size:14}),onClick:()=>{te(V),E("list")},children:j("entityEditor.delete","Delete")})})]}),e.jsx(c.NiceTabs,{tabs:_,activeTab:S,onChange:O,variant:"enclosed"})]}):e.jsx("div",{className:"nice-entity-editor__list-view",children:e.jsx(c.NiceDataGrid,{data:T,keyField:ke,columns:ae,searchable:!0,searchPlaceholder:j("entityEditor.search","Search entities…"),emptyText:j("entityEditor.empty","No entities yet. Create one to get started."),onRowClick:x=>G(Number(x[ke])),onRowDelete:v?void 0:x=>te(Number(x)),toolbar:v?void 0:e.jsx(c.NiceButton,{variant:"primary",size:"sm",leftIcon:e.jsx(c.NiceIcon,{name:"plus",size:14}),onClick:ee,children:j("entityEditor.new","New entity")}),compact:!0,striped:!0})})]})}),mt=4e6;function pt(t,a){const o=t.split(/\r?\n/),r=a.split(/\r?\n/);if(o.length*r.length>mt)return[...o.map(d=>({type:"remove",text:d})),...r.map(d=>({type:"add",text:d}))];const u=o.length,i=r.length,s=Array.from({length:u+1},()=>new Uint32Array(i+1));for(let d=u-1;d>=0;d--)for(let p=i-1;p>=0;p--)s[d][p]=o[d]===r[p]?s[d+1][p+1]+1:Math.max(s[d+1][p],s[d][p+1]);const l=[];let n=0,m=0;for(;n<u&&m<i;)o[n]===r[m]?(l.push({type:"same",text:o[n]}),n++,m++):s[n+1][m]>=s[n][m+1]?l.push({type:"remove",text:o[n++]}):l.push({type:"add",text:r[m++]});for(;n<u;)l.push({type:"remove",text:o[n++]});for(;m<i;)l.push({type:"add",text:r[m++]});return l}function De({before:t,after:a,context:o=3}){const{t:r}=c.useNiceTranslation(),u=g.useMemo(()=>{const i=pt(t,a),s=new Set;i.forEach((m,d)=>{if(m.type!=="same")for(let p=Math.max(0,d-o);p<=Math.min(i.length-1,d+o);p++)s.add(p)});const l=[];let n=0;return i.forEach((m,d)=>{s.has(d)?(n>0&&(l.push({type:"gap",count:n}),n=0),l.push(m)):n++}),n>0&&l.length>0&&l.push({type:"gap",count:n}),l},[t,a,o]);return u.length===0?e.jsx("p",{className:"nice-development-studio__muted",children:r("devStudio.diff.none","No changes.")}):e.jsx("pre",{className:"nice-development-studio__diff","aria-label":r("devStudio.diff.label","Changes"),children:u.map((i,s)=>i.type==="gap"?e.jsxs("span",{className:"nice-development-studio__diff-gap",children:[r("devStudio.diff.unchanged","{count} unchanged lines").replace("{count}",String(i.count)),`
|
|
4
|
-
`]},
|
|
5
|
-
`]},s))})}function ht({open:t,onClose:a,session:o,preset:r,locales:u,prefill:i,onCreated:s}){var $,M,b,E;const{t:l}=c.useNiceTranslation(),n=o.workspaces.filter(h=>!h.readOnly),m=r.requiredLocales??[],[d,p]=g.useState(()=>{var h;return{workspaceId:i.workspaceId&&n.some(y=>y.id===i.workspaceId)?i.workspaceId:((h=n[0])==null?void 0:h.id)??"",packageId:i.packageId,name:"",entities:[{name:"Item",fields:[{name:"Id",dataType:"Guid",isPrimaryKey:!0,isRequired:!0},{name:"Name",dataType:"string",isRequired:!0,maxLength:200}]}],locales:[...new Set([...m,...u.slice(0,2)])],views:!0,permissions:!0}}),[v,k]=g.useState(null),[w,A]=g.useState(!1),R=g.useMemo(()=>[...new Set((o.modulesByWs[d.workspaceId]??[]).map(h=>h.packageId).filter(Boolean))].sort(),[o.modulesByWs,d.workspaceId]);if(!t)return null;const L=new Set(Object.values(o.modulesByWs).flatMap(h=>h.map(y=>y.id))),j=async()=>{r.generateModule&&d.name.trim()&&k(await r.generateModule({...d,name:d.name.trim()},{existingIds:L}))};return e.jsx(c.NiceModal,{open:t,onClose:a,title:l("devStudio.wizard.title","New module"),size:"xl","data-testid":"studio-module-wizard",children:e.jsx(c.NiceWizard,{finishLabel:l("devStudio.wizard.create","Create module"),onCancel:a,onStepChange:h=>{h===3&&j()},onComplete:async()=>{if(w)return;A(!0);const h=await o.createModule({...d,name:d.name.trim()});A(!1),h&&(s({workspaceId:h.workspaceId,id:h.id}),a())},steps:[{id:"identity",title:l("devStudio.wizard.identity","Name and place"),validate:()=>d.name.trim()&&d.workspaceId?!0:l("devStudio.wizard.needName","Give the module a name."),content:e.jsxs("div",{className:"nice-development-studio__form",children:[e.jsx(c.NiceSelect,{label:l("devStudio.wizard.workspace","Project"),value:d.workspaceId,options:n.map(h=>({value:h.id,label:h.label})),onChange:h=>p({...d,workspaceId:String(h)})}),e.jsx(c.NiceTextInput,{label:l("devStudio.wizard.package","Package"),value:d.packageId??"",placeholder:R.join(", "),onChange:h=>p({...d,packageId:h||void 0})}),e.jsx(c.NiceTextInput,{label:l("devStudio.wizard.name","Name"),value:d.name,placeholder:l("devStudio.wizard.namePlaceholder","e.g. Bike rental"),onChange:h=>p({...d,name:h})}),e.jsx(c.NiceTextInput,{label:l("devStudio.wizard.description","Description"),value:d.description??"",onChange:h=>p({...d,description:h||void 0})})]})},{id:"entities",title:l("devStudio.wizard.entities","Entities"),content:e.jsx(Te,{value:d.entities,onChange:h=>p({...d,entities:h}),entityMetaSchema:($=r.entities)==null?void 0:$.entityMetaSchema,fieldSchema:(M=r.entities)==null?void 0:M.fieldSchema,fieldsKey:(b=r.entities)==null?void 0:b.fieldsKey,nameKey:(E=r.entities)==null?void 0:E.nameKey})},{id:"options",title:l("devStudio.wizard.options","Options"),content:e.jsxs("div",{className:"nice-development-studio__form",children:[e.jsxs("fieldset",{className:"nice-development-studio__fieldset",children:[e.jsx("legend",{children:l("devStudio.wizard.locales","Languages")}),[...new Set([...m,...u])].map(h=>e.jsx(c.NiceCheckbox,{label:h,checked:d.locales.includes(h),disabled:m.includes(h),onChange:y=>p({...d,locales:y?[...d.locales,h]:d.locales.filter(S=>S!==h)})},h))]}),e.jsx(c.NiceCheckbox,{label:l("devStudio.wizard.views","A list and a form view per entity"),checked:!!d.views,onChange:h=>p({...d,views:h})}),e.jsx(c.NiceCheckbox,{label:l("devStudio.wizard.permissions","Viewer, editor and admin permissions"),checked:!!d.permissions,onChange:h=>p({...d,permissions:h})})]})},{id:"review",title:l("devStudio.wizard.review","Review"),content:v?e.jsxs("div",{children:[e.jsx("p",{children:l("devStudio.wizard.willCreate","Module {id} with these files:").replace("{id}",v.id)}),e.jsx("ul",{className:"nice-development-studio__list",children:v.files.map(h=>e.jsxs("li",{children:[e.jsx(c.NiceIcon,{name:"file",size:12})," ",h.path]},h.path))})]}):e.jsx("p",{className:"nice-development-studio__muted",children:l("devStudio.wizard.generating","Generating…")})}]})})}function ft({open:t,moduleLabel:a,changes:o,original:r,conflict:u,onSave:i,onOverwrite:s,onReload:l,onClose:n}){const{t:m}=c.useNiceTranslation();return t?e.jsxs(c.NiceModal,{open:t,onClose:n,size:"xl",title:m("devStudio.review.title","Save {module}").replace("{module}",a),"data-testid":"studio-review",footer:u?e.jsxs(e.Fragment,{children:[e.jsx(c.NiceButton,{variant:"ghost",onClick:n,children:m("devStudio.cancel","Cancel")}),e.jsx(c.NiceButton,{variant:"secondary",onClick:l,children:m("devStudio.review.reload","Reload theirs (drop mine)")}),e.jsx(c.NiceButton,{variant:"danger",onClick:s,children:m("devStudio.review.overwrite","Overwrite with mine")})]}):e.jsxs(e.Fragment,{children:[e.jsx(c.NiceButton,{variant:"ghost",onClick:n,children:m("devStudio.cancel","Cancel")}),e.jsx(c.NiceButton,{variant:"primary",onClick:i,children:m("devStudio.review.save","Save {count} files").replace("{count}",String(o.length))})]}),children:[u&&e.jsxs("p",{className:"nice-development-studio__error",role:"alert",children:[m("devStudio.review.conflict","These files changed since you opened them:")," ",u.conflicts.map(d=>d.path).join(", ")]}),o.map(d=>e.jsxs("section",{className:"nice-development-studio__source",children:[e.jsx("h4",{className:"nice-development-studio__source-title",children:d.type==="delete"?m("devStudio.change.delete","Delete {path}").replace("{path}",d.path):d.baseVersion===void 0&&!r(d.path)?m("devStudio.change.new","New file {path}").replace("{path}",d.path):d.path}),e.jsx(De,{before:r(d.path),after:d.type==="write"?d.text:""})]},d.path))]}):null}function vt({open:t,moduleId:a,templates:o,onApply:r,onClose:u}){const{t:i}=c.useNiceTranslation(),s=g.useMemo(()=>o.filter(p=>p.modules.some(v=>v.moduleId===a)).map(p=>p.id),[o,a]),[l,n]=g.useState(s);if(!t)return null;const m=o.map(p=>{var v,k;return{id:p.id,label:((v=p.translations.en)==null?void 0:v.name)??((k=Object.values(p.translations)[0])==null?void 0:k.name)??p.id}}),d=[{field:"label",header:i("devStudio.explorer.name","Name")}];return e.jsx(c.NiceModal,{open:t,onClose:u,title:i("devStudio.picker.title","Templates with {module}").replace("{module}",a),"data-testid":"studio-template-picker",footer:e.jsxs(e.Fragment,{children:[e.jsx(c.NiceButton,{variant:"ghost",onClick:u,children:i("devStudio.cancel","Cancel")}),e.jsx(c.NiceButton,{variant:"primary",onClick:()=>{const p=o.filter(v=>l.includes(v.id)!==s.includes(v.id)).map(v=>({...v,modules:l.includes(v.id)?[...v.modules,{moduleId:a}]:v.modules.filter(k=>k.moduleId!==a)}));r(p)},children:i("devStudio.apply","Apply")})]}),children:e.jsx(c.NiceTreeGrid,{data:m,columns:d,keyField:"id",sortable:!1,compact:!0,checkable:!0,checkedKeys:l,onCheckedChange:n,searchable:!0,"aria-label":i("devStudio.explorer.templates","Templates")})})}function Fe({open:t,title:a,workspaces:o,workspaceId:r,idLabel:u,initialId:i="",withLabel:s,onSubmit:l,onClose:n}){var R;const{t:m}=c.useNiceTranslation(),[d,p]=g.useState(r??((R=o[0])==null?void 0:R.id)??""),[v,k]=g.useState(i),[w,A]=g.useState("");return t?e.jsx(c.NiceModal,{open:t,onClose:n,title:a,footer:e.jsxs(e.Fragment,{children:[e.jsx(c.NiceButton,{variant:"ghost",onClick:n,children:m("devStudio.cancel","Cancel")}),e.jsx(c.NiceButton,{variant:"primary",disabled:!v.trim()||!d,onClick:()=>l({workspaceId:d,id:v.trim(),label:w.trim()||v.trim()}),children:m("devStudio.ok","OK")})]}),children:e.jsxs("div",{className:"nice-development-studio__form",children:[e.jsx(c.NiceSelect,{label:m("devStudio.wizard.workspace","Project"),value:d,options:o.map(L=>({value:L.id,label:L.label})),onChange:L=>p(String(L))}),e.jsx(c.NiceTextInput,{label:u,value:v,onChange:k}),s&&e.jsx(c.NiceTextInput,{label:m("devStudio.package.label","Name"),value:w,onChange:A})]})}):null}const gt=[{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"}],Ce=g.forwardRef(function(a,o){const{value:r,defaultValue:u,onChange:i,locales:s,allowEditLocales:l=!0,allowEditKeys:n=!0,highlightMissing:m=!0,readOnly:d=!1,tutorial:p,className:v,style:k,id:w,"data-testid":A}=a,{t:R}=ue.useNiceTranslation(),[L,j]=ue.useControllableState({value:r,defaultValue:u,fallbackValue:{},onChange:i,componentName:"NiceI18nEditor"}),[$,M]=g.useState(""),[b,E]=g.useState(""),h=g.useMemo(()=>s??Object.keys(L),[s,L]),y=g.useMemo(()=>{const K=new Set;for(const T of Object.keys(L))for(const F of Object.keys(L[T]??{}))K.add(F);return[...K].sort()},[L]),S=(K,T,F)=>{j({...L,[K]:{...L[K]??{},[T]:F}})},O=(K,T)=>{if(!T||T===K)return;const F={};for(const H of Object.keys(L)){const G={...L[H]??{}};K in G&&(G[T]=G[K],delete G[K]),F[H]=G}j(F)},V=K=>{const T={};for(const F of Object.keys(L)){const H={...L[F]??{}};delete H[K],T[F]=H}j(T)},N=()=>{const K=$.trim();if(!K||y.includes(K))return;const T={};for(const F of h)T[F]={...L[F]??{},[K]:""};for(const F of Object.keys(L))T[F]||(T[F]=L[F]);j(T),M("")},J=()=>{const K=b.trim();if(!K||L[K])return;const T={};for(const F of y)T[F]="";j({...L,[K]:T}),E("")},X=K=>{const T={...L};delete T[K],j(T)},Q="nice-i18n-editor"+(v?` ${v}`:"");return e.jsxs("div",{ref:o,id:w,className:Q,style:k,"data-testid":A,children:[p&&e.jsx("div",{className:"nice-i18n-editor__tutorial",children:e.jsx(ue.NiceTutorialButton,{steps:ue.resolveTutorial(p,gt)})}),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:R("i18nEditor.keyHead","Key")}),h.map(K=>e.jsxs("th",{className:"nice-i18n-editor__locale-head",children:[e.jsx("span",{children:K}),l&&!d&&e.jsx("button",{type:"button",className:"nice-i18n-editor__locale-remove","aria-label":`${R("i18nEditor.removeLocale","Remove locale")} ${K}`,onClick:()=>X(K),children:e.jsx(ue.NiceIcon,{name:"close",size:12})})]},K))]})}),e.jsxs("tbody",{children:[y.map(K=>e.jsxs("tr",{children:[e.jsxs("td",{className:"nice-i18n-editor__key-cell",children:[n&&!d?e.jsx("input",{className:"nice-i18n-editor__key-input",defaultValue:K,onBlur:T=>O(K,T.target.value.trim()),"aria-label":R("i18nEditor.keyAria","Translation key")}):e.jsx("span",{className:"nice-i18n-editor__key-text",children:K}),n&&!d&&e.jsx("button",{type:"button",className:"nice-i18n-editor__key-remove","aria-label":`${R("i18nEditor.removeKey","Remove key")} ${K}`,onClick:()=>V(K),children:e.jsx(ue.NiceIcon,{name:"close",size:12})})]}),h.map(T=>{var G;const F=((G=L[T])==null?void 0:G[K])??"",H=m&&F==="";return e.jsx("td",{className:"nice-i18n-editor__cell",children:e.jsx("input",{className:"nice-i18n-editor__cell-input"+(H?" nice-i18n-editor__cell-input--missing":""),value:F,readOnly:d,onChange:ee=>S(T,K,ee.target.value),"aria-label":`${K} (${T})`})},T)})]},K)),y.length===0&&e.jsx("tr",{children:e.jsx("td",{className:"nice-i18n-editor__empty",colSpan:h.length+1,children:R("i18nEditor.empty","No translation keys yet.")})})]})]})}),!d&&(n||l)&&e.jsxs("div",{className:"nice-i18n-editor__toolbar","data-tour":"i18n-add",children:[n&&e.jsxs("div",{className:"nice-i18n-editor__add",children:[e.jsx("input",{className:"nice-i18n-editor__add-input",placeholder:R("i18nEditor.newKeyPlaceholder","new.key"),value:$,onChange:K=>M(K.target.value),onKeyDown:K=>{K.key==="Enter"&&N()},"aria-label":R("i18nEditor.newKeyAria","New key")}),e.jsxs("button",{type:"button",onClick:N,children:["+ ",R("i18nEditor.addKey","Key")]})]}),l&&e.jsxs("div",{className:"nice-i18n-editor__add",children:[e.jsx("input",{className:"nice-i18n-editor__add-input",placeholder:R("i18nEditor.newLocalePlaceholder","locale (e.g. de)"),value:b,onChange:K=>E(K.target.value),onKeyDown:K=>{K.key==="Enter"&&J()},"aria-label":R("i18nEditor.newLocaleAria","New locale")}),e.jsxs("button",{type:"button",onClick:J,children:["+ ",R("i18nEditor.addLocale","Locale")]})]})]})]})}),Oe=t=>JSON.stringify(t??null,null,2);function ve({value:t,onChange:a,readOnly:o,height:r=320,label:u}){const{t:i}=c.useNiceTranslation(),[s,l]=g.useState(()=>Oe(t)),[n,m]=g.useState(null),d=g.useRef(t);return g.useEffect(()=>{d.current!==t&&(d.current=t,l(Oe(t)),m(null))},[t]),e.jsxs("div",{className:"nice-development-studio__json",role:"group","aria-label":u,children:[e.jsx(c.NiceSimpleCodeEditor,{value:s,language:"json",height:r,readOnly:o,lineNumbers:!0,onChange:p=>{l(p);try{const v=JSON.parse(p);m(null),d.current=v,a==null||a(v)}catch(v){m(v instanceof Error?v.message:String(v))}}}),n&&e.jsxs("p",{className:"nice-development-studio__error",role:"alert",children:[i("devStudio.json.invalid","Not valid JSON:")," ",n]})]})}function Pe(t){return t.documents.filter(a=>a.kind.editor==="entities").flatMap(a=>t.drafts[a.key]??a.model??[])}function yt(t){return t.documents.filter(a=>a.kind.editor==="dataSources").flatMap(a=>t.drafts[a.key]??a.model??[])}function xt(t){const{module:a,doc:o,session:r,readOnly:u}=t,{t:i}=c.useNiceTranslation(),[s,l]=g.useState(o.model===void 0?"source":"visual"),n=a.changes.filter(d=>o.paths.includes(d.path)||!a.files.some(p=>p.path===d.path)&&o.kind.match(d.path)),m=[{id:"visual",label:i("devStudio.doc.visual","Editor")},{id:"source",label:i("devStudio.doc.source","Source")},{id:"changes",label:`${i("devStudio.doc.changes","Changes")}${n.length?` (${n.length})`:""}`}];return e.jsxs("div",{className:"nice-development-studio__document","data-testid":`studio-doc-${o.key}`,children:[e.jsxs("div",{className:"nice-development-studio__doc-bar",children:[e.jsx(c.NiceIcon,{name:o.kind.icon??"file",size:14}),e.jsx("strong",{className:"nice-development-studio__doc-title",children:o.label}),e.jsx("span",{className:"nice-development-studio__muted",children:o.paths.length===1?o.paths[0]:i("devStudio.doc.files","{count} files").replace("{count}",String(o.paths.length))}),e.jsx("span",{className:"nice-development-studio__spacer"}),e.jsx("div",{className:"nice-development-studio__segmented",role:"group","aria-label":i("devStudio.doc.mode","Show"),children:m.map(d=>e.jsx(c.NiceButton,{size:"sm",variant:s===d.id?"primary":"ghost","aria-pressed":s===d.id,disabled:d.id==="visual"&&o.model===void 0,onClick:()=>l(d.id),children:d.label},d.id))})]}),o.error&&e.jsxs("p",{className:"nice-development-studio__error",role:"alert",children:[i("devStudio.doc.unreadable","This file could not be read as its kind; edit its source.")," ",o.error]}),s==="visual"&&o.model!==void 0&&e.jsx(bt,{...t}),s==="source"&&e.jsx("div",{className:"nice-development-studio__sources",children:o.paths.map(d=>e.jsxs("section",{className:"nice-development-studio__source",children:[e.jsx("h4",{className:"nice-development-studio__source-title",children:d}),e.jsx(c.NiceSimpleCodeEditor,{value:a.pending.get(d)??"",language:d.endsWith(".json")?"json":d.endsWith(".js")?"javascript":"plaintext",height:360,lineNumbers:!0,readOnly:u,onChange:p=>r.setRaw(a.key,d,P.keepTextFormat(p,a.pending.get(d)),[o.key])})]},d))}),s==="changes"&&e.jsxs("div",{className:"nice-development-studio__sources",children:[n.length===0&&e.jsx("p",{className:"nice-development-studio__muted",children:i("devStudio.diff.none","No changes.")}),n.map(d=>{var p;return e.jsxs("section",{className:"nice-development-studio__source",children:[e.jsx("h4",{className:"nice-development-studio__source-title",children:d.type==="delete"?i("devStudio.change.delete","Delete {path}").replace("{path}",d.path):a.files.some(v=>v.path===d.path)?d.path:i("devStudio.change.new","New file {path}").replace("{path}",d.path)}),e.jsx(De,{before:((p=a.files.find(v=>v.path===d.path))==null?void 0:p.text)??"",after:d.type==="write"?d.text:""})]},d.path)})]})]})}function bt(t){var m,d,p,v,k,w;const{module:a,doc:o,preset:r,session:u,locales:i,readOnly:s}=t,l=a.drafts[o.key]??o.model,n=A=>u.setDraft(a.key,o.key,A);switch(o.kind.editor){case"manifest":return e.jsx(kt,{value:l??{},onChange:n,sections:r.manifestSections??[],readOnly:s});case"entities":return e.jsx(Te,{value:l??[],onChange:n,entityMetaSchema:(m=r.entities)==null?void 0:m.entityMetaSchema,fieldSchema:(d=r.entities)==null?void 0:d.fieldSchema,fieldsKey:(p=r.entities)==null?void 0:p.fieldsKey,nameKey:(v=r.entities)==null?void 0:v.nameKey,readOnly:s});case"i18n":{const A=l??{};return e.jsx(Ce,{value:A,onChange:n,locales:[...new Set([...i,...Object.keys(A)])],allowEditLocales:!0,allowEditKeys:!0,highlightMissing:!0,readOnly:s})}case"views":return e.jsx(jt,{...t,items:l??[],onChange:n});case"workflows":return e.jsx(Le,{items:l??[],onChange:n,readOnly:s,kind:"workflow",create:A=>({id:`workflow-${A}`,name:`Workflow ${A}`,entityType:"",version:1,states:[],transitions:[]}),render:(A,R)=>e.jsx(c.NiceWorkflowDesigner,{workflow:A,onChange:R,readOnly:s})});case"permissions":return e.jsx(St,{value:l??{permissions:[],groups:[]},onChange:n,readOnly:s});case"rbac":return e.jsx(c.NiceAccessManager,{value:l,onChange:n,readOnly:s});case"dataSources":return e.jsx(Nt,{value:l??[],onChange:n,entities:Pe(a),readOnly:s});case"seeds":return e.jsx(wt,{value:l??{seeds:{}},onChange:n,readOnly:s});case"hooks":return e.jsx(c.NiceLifecycleHooksEditor,{triggers:((k=r.hooks)==null?void 0:k.triggers)??[],handlers:(w=r.hooks)==null?void 0:w.handlers,bindings:l??[],onChange:n,groupByTrigger:!0,allowCondition:!0,readOnly:s});case"script":return t.scriptRunner?e.jsx(c.NiceScriptRunner,{...t.scriptRunner,value:String(l??""),onChange:n}):e.jsx(c.NiceSimpleCodeEditor,{value:String(l??""),onChange:n,language:"javascript",height:420,lineNumbers:!0,readOnly:s});case"text":return e.jsx(c.NiceSimpleCodeEditor,{value:String(l??""),onChange:n,height:420,lineNumbers:!0,readOnly:s});default:return e.jsx(ve,{value:l,onChange:n,readOnly:s,height:420,label:o.label})}}function kt({value:t,onChange:a,sections:o,readOnly:r}){const{t:u}=c.useNiceTranslation(),i=g.useMemo(()=>o.map(m=>P.fitManifestSection(m,t)),[o,t]),s=g.useMemo(()=>new Set(i.flatMap(m=>m.keys)),[i]),l=g.useMemo(()=>Object.fromEntries(Object.entries(t).filter(([m])=>!s.has(m))),[t,s]),n=e.jsx(ve,{value:l,readOnly:r,label:u("devStudio.manifest.other","Other properties"),onChange:m=>{if(m&&typeof m=="object"&&!Array.isArray(m)){const d=Object.fromEntries(Object.entries(t).filter(([p])=>s.has(p)));a({...d,...m})}}});return o.length===0?n:e.jsx(c.NiceTabs,{tabs:[...i.map(({section:m,keys:d})=>({id:m.id,label:m.title,content:e.jsx(pe,{schema:m.schema,fields:m.fields,uiSchema:m.uiSchema,value:Object.fromEntries(d.filter(p=>p in t).map(p=>[p,t[p]])),onChange:p=>{const v={...t};for(const k of d)p[k]===void 0?delete v[k]:v[k]=p[k];a(v)},readOnly:r,showJsonView:!0})})),{id:"__other",label:u("devStudio.manifest.other","Other properties"),content:n}]})}function Le({items:t,onChange:a,readOnly:o,kind:r,create:u,render:i}){var v;const{t:s}=c.useNiceTranslation(),[l,n]=g.useState(((v=t[0])==null?void 0:v.key)??null),m=t.find(k=>k.key===l)??null,d=r==="view"?{pick:s("devStudio.items.pickView","View"),add:s("devStudio.items.addView","New view"),empty:s("devStudio.items.noViews","No views yet.")}:{pick:s("devStudio.items.pickWorkflow","Workflow"),add:s("devStudio.items.addWorkflow","New workflow"),empty:s("devStudio.items.noWorkflows","No workflows yet.")},p=(k,w)=>{a(t.map(A=>A.key===k?w:A)),w.key!==k&&n(w.key)};return e.jsxs("div",{className:"nice-development-studio__items",children:[e.jsxs("div",{className:"nice-development-studio__items-bar",children:[e.jsxs("label",{className:"nice-development-studio__field",children:[e.jsx("span",{children:d.pick}),e.jsxs("select",{value:l??"",onChange:k=>n(k.target.value||null),children:[t.length===0&&e.jsx("option",{value:"",children:d.empty}),t.map(k=>e.jsxs("option",{value:k.key,children:[k.label,k.definition?"":` (${s("devStudio.items.raw","JSON")})`]},k.key))]})]}),!o&&e.jsxs(e.Fragment,{children:[e.jsx(c.NiceButton,{size:"sm",variant:"ghost",leftIcon:e.jsx(c.NiceIcon,{name:"plus",size:14}),onClick:()=>{const k=u(t.length+1),w={key:k.id,label:k.name,definition:k,source:k};a([...t,w]),n(w.key)},children:d.add}),m&&e.jsx(c.NiceButton,{size:"sm",variant:"ghost",leftIcon:e.jsx(c.NiceIcon,{name:"trash",size:14}),onClick:()=>{a(t.filter(k=>k.key!==m.key)),n(null)},children:s("devStudio.delete","Delete")})]})]}),(m==null?void 0:m.definition)!==void 0&&i(m.definition,k=>p(m.key,{...m,definition:k,label:k.name||m.label,key:k.id&&!t.some(w=>w!==m&&w.key===k.id)?k.id:m.key}),m),m&&m.definition===void 0&&e.jsxs(e.Fragment,{children:[e.jsxs("p",{className:"nice-development-studio__muted",children:[s("devStudio.items.rawReason","The editor does not know this shape, so it is edited as JSON."),m.rawReason?` (${m.rawReason})`:""]}),e.jsx(ve,{value:m.source,readOnly:o,label:m.label,onChange:k=>p(m.key,{...m,source:k})})]}),!m&&e.jsx("p",{className:"nice-development-studio__muted",children:d.empty})]})}function jt({module:t,items:a,onChange:o,readOnly:r,renderViewPreview:u}){const{t:i}=c.useNiceTranslation(),s=Pe(t),l=yt(t).map(n=>({key:n.key,label:n.label}));return e.jsx(Le,{items:a,onChange:o,readOnly:r,kind:"view",create:n=>({id:`view-${n}`,name:`View ${n}`,version:2,columns:12,rows:[],dataSources:[]}),render:(n,m,d)=>{const p=e.jsx(c.NiceViewEditor,{value:n,onChange:m,entities:s,dataSourceOptions:l,height:540});return u?e.jsx(c.NiceTabs,{tabs:[{id:"design",label:i("devStudio.view.design","Design"),content:p},{id:"preview",label:i("devStudio.view.hostPreview","Preview in the app"),content:u({module:t.key,item:{...d,definition:n},files:t.working})}]}):p}})}function Nt({value:t,onChange:a,entities:o,readOnly:r}){var m;const{t:u}=c.useNiceTranslation(),[i,s]=g.useState(((m=t[0])==null?void 0:m.key)??null),l=t.find(d=>d.key===i)??null,n=g.useMemo(()=>P.entitiesToSchemas(o),[o]);return e.jsxs("div",{className:"nice-development-studio__items",children:[e.jsxs("div",{className:"nice-development-studio__items-bar",children:[e.jsxs("label",{className:"nice-development-studio__field",children:[e.jsx("span",{children:u("devStudio.items.pickDataSource","Data source")}),e.jsxs("select",{value:i??"",onChange:d=>s(d.target.value||null),children:[t.length===0&&e.jsx("option",{value:"",children:u("devStudio.items.noDataSources","No data sources yet.")}),t.map(d=>e.jsx("option",{value:d.key,children:d.label||d.key},d.key))]})]}),!r&&e.jsx(c.NiceButton,{size:"sm",variant:"ghost",leftIcon:e.jsx(c.NiceIcon,{name:"plus",size:14}),onClick:()=>{const d={key:`source${t.length+1}`,kind:"query",query:{tables:[],joins:[],conditions:[],sorts:[],groupBy:[],distinct:!1},sql:""};a([...t,d]),s(d.key)},children:u("devStudio.items.addDataSource","New data source")})]}),l&&e.jsx(c.NiceDataSourceBuilder,{value:l,schemas:n,onChange:d=>{a(t.map(p=>p.key===l.key?d:p)),s(d.key)}})]})}function St({value:t,onChange:a,readOnly:o}){const{t:r}=c.useNiceTranslation(),u={code:r("devStudio.permissions.code","Code"),name:r("devStudio.permissions.name","Name"),description:r("devStudio.permissions.description","Description")},i=g.useMemo(()=>{const l={};for(const n of t.groups)for(const m of n.permissions)l[`${n.id}:${m}`]=!0;return l},[t.groups]),s=(l,n)=>{const m=t.permissions[l],d={...m,...n};a({permissions:t.permissions.map((p,v)=>v===l?d:p),groups:n.code!==void 0&&n.code!==m.code?t.groups.map(p=>({...p,permissions:p.permissions.map(v=>v===m.code?d.code:v)})):t.groups})};return e.jsxs("div",{className:"nice-development-studio__permissions",children:[e.jsx("h4",{children:r("devStudio.permissions.codes","Permissions")}),e.jsxs("table",{className:"nice-development-studio__table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:u.code}),e.jsx("th",{children:u.name}),e.jsx("th",{children:u.description}),!o&&e.jsx("th",{"aria-label":r("devStudio.delete","Delete")})]})}),e.jsx("tbody",{children:t.permissions.map((l,n)=>e.jsxs("tr",{children:[["code","name","description"].map(m=>e.jsx("td",{children:e.jsx("input",{className:"nice-development-studio__cell",value:l[m]??"",readOnly:o,"aria-label":`${u[m]} ${l.code}`,onChange:d=>s(n,{[m]:d.target.value})})},m)),!o&&e.jsx("td",{children:e.jsx(c.NiceButton,{size:"sm",variant:"ghost",ariaLabel:`${r("devStudio.delete","Delete")} ${l.code}`,onClick:()=>a({permissions:t.permissions.filter((m,d)=>d!==n),groups:t.groups.map(m=>({...m,permissions:m.permissions.filter(d=>d!==l.code)}))}),children:e.jsx(c.NiceIcon,{name:"trash",size:14})})})]},n))})]}),!o&&e.jsxs("div",{className:"nice-development-studio__row",children:[e.jsx(c.NiceButton,{size:"sm",variant:"ghost",leftIcon:e.jsx(c.NiceIcon,{name:"plus",size:14}),onClick:()=>a({...t,permissions:[...t.permissions,{code:`New.Permission${t.permissions.length+1}`}]}),children:r("devStudio.permissions.addCode","New permission")}),e.jsx(c.NiceButton,{size:"sm",variant:"ghost",leftIcon:e.jsx(c.NiceIcon,{name:"plus",size:14}),onClick:()=>a({...t,groups:[...t.groups,{id:`group${t.groups.length+1}`,label:r("devStudio.permissions.newGroup","Group {n}").replace("{n}",String(t.groups.length+1)),permissions:[]}]}),children:r("devStudio.permissions.addGroup","New group")})]}),e.jsx("h4",{children:r("devStudio.permissions.groups","Groups")}),e.jsx(c.NicePermissionMatrix,{roles:t.groups.map(l=>({id:l.id,label:l.label})),actions:t.permissions.map(l=>({id:l.code,label:l.name||l.code})),value:i,readOnly:o,showBulkActions:!0,onChange:l=>a({...t,groups:t.groups.map(n=>({...n,permissions:t.permissions.map(m=>m.code).filter(m=>l[`${n.id}:${m}`]===!0)}))})})]})}function wt({value:t,onChange:a,readOnly:o}){const{t:r}=c.useNiceTranslation(),u=i=>{const s=t[i]??{},l=Object.keys(s);return l.length===0?e.jsx("p",{className:"nice-development-studio__muted",children:r("devStudio.seeds.empty","No rows.")}):e.jsx(c.NiceTabs,{tabs:l.map(n=>({id:n,label:`${n} (${s[n].length})`,content:e.jsx(ve,{value:s[n],readOnly:o,label:n,onChange:m=>{Array.isArray(m)&&a({...t,[i]:{...s,[n]:m}})}})}))})};return e.jsx(c.NiceTabs,{tabs:[{id:"seeds",label:r("devStudio.seeds.data","Data"),content:u("seeds")},{id:"demo",label:r("devStudio.seeds.demo","Demo data"),content:u("demoSeeds")}]})}const Y=t=>`${t.workspaceId}/${t.id}`;function Se(t,a,o){const r=new Set(t.deleted),u=new Map;for(const v of t.files)r.has(v.path)||u.set(v.path,t.raw[v.path]!==void 0?{...v,text:t.raw[v.path]}:v);for(const[v,k]of Object.entries(t.raw))!u.has(v)&&!r.has(v)&&u.set(v,{path:v,text:k});const i=[...u.values()],s={moduleId:t.key.id,files:i,locales:o},l=P.buildDocuments(a.kinds,i,s),n=new Map(i.map(v=>[v.path,v.text])),m={};for(const v of l)if(v.key in t.drafts)try{const k=v.kind.encode(t.drafts[v.key],i.filter(w=>v.paths.includes(w.path)),s);for(const w of k.files)n.set(w.path,w.text),r.delete(w.path);for(const w of k.deleted??[])n.delete(w),r.add(w)}catch(k){m[v.key]=k instanceof Error?k.message:String(k)}const d=new Map(t.files.map(v=>[v.path,v])),p=[];for(const[v,k]of n){const w=d.get(v);(!w||w.text!==k)&&p.push({type:"write",path:v,text:k,baseVersion:w==null?void 0:w.version})}for(const v of r){const k=d.get(v);k&&p.push({type:"delete",path:v,baseVersion:k.version})}return{...t,working:i,documents:l,changes:p,pending:n,encodeErrors:m,dirty:p.length>0}}function Ae(t,a){const o=[];for(const r of t.documents){if(r.error&&o.push({severity:"error",code:"file.unreadable",message:`${r.paths[0]} cannot be read: ${r.error}`,messageKey:"devStudio.issue.unreadable",params:{path:r.paths[0]},moduleId:t.key.id,path:r.paths[0]}),r.kind.editor!=="manifest"||!a.manifestSections)continue;const u=t.drafts[r.key]??r.model??{};for(const i of a.manifestSections){const{section:s}=P.fitManifestSection(i,u);if(s.schema)for(const l of Ie(u,s.schema))o.push({severity:"error",code:"manifest.schema",message:`${s.title}: ${l.field} — ${l.message}`,moduleId:t.key.id,path:r.paths[0],pointer:`/${l.field.replace(/\./g,"/")}`})}}for(const[r,u]of Object.entries(t.encodeErrors))o.push({severity:"error",code:"document.encode",message:`${r}: ${u}`,moduleId:t.key.id});if(a.validateModule){const r=[...t.pending.entries()].map(([u,i])=>({path:u,text:i}));o.push(...a.validateModule({key:t.key,files:r,documents:t.documents}).map(u=>({...u,moduleId:u.moduleId??t.key.id})))}return o}const _t=t=>t instanceof Error?t.message:String(t);function It(t,a,o){const[r,u]=g.useState([]),[i,s]=g.useState({}),[l,n]=g.useState({}),[m,d]=g.useState(null),[p,v]=g.useState({}),[k,w]=g.useState({}),[A,R]=g.useState(0),[L,j]=g.useState([]),$=g.useRef({provider:t,preset:a,options:o});$.current={provider:t,preset:a,options:o};const M=g.useCallback((_,I,x)=>{j(C=>[...C,{level:_,message:I,data:x,timestamp:Date.now()}].slice(-300))},[]),b=g.useCallback(async(_,I)=>{var x,C;R(B=>B+1);try{return await I()}catch(B){M("error",`${_}: ${_t(B)}`),(C=(x=$.current.options).onError)==null||C.call(x,B,_);return}finally{R(B=>B-1)}},[M]),E=g.useCallback(async()=>{const _=$.current.provider;_&&await b("List",async()=>{const I=await _.listWorkspaces();u(I);const x=await Promise.all(I.map(async C=>{const[B,q]=await Promise.all([_.listModules(C.id),_.listPackages?_.listPackages(C.id):Promise.resolve(void 0)]);return[C.id,B,q]}));s(Object.fromEntries(x.map(([C,B])=>[C,B]))),n(Object.fromEntries(x.filter(([,,C])=>C).map(([C,,B])=>[C,B]))),d(_.listTemplates?await _.listTemplates():null)})},[b]);g.useEffect(()=>{E()},[t,E]);const h=g.useMemo(()=>{const _={};for(const[I,x]of Object.entries(p))_[I]=Se(x,a,o.locales);return _},[p,a,o.locales]),y=g.useCallback(async _=>{const I=Y(_),x=$.current.provider;if(!x)return;const C=await b(`Open ${_.id}`,()=>x.readModule(_));if(!C)return;const B={key:_,files:C,raw:{},deleted:[],drafts:{}};return v(q=>q[I]?q:{...q,[I]:B}),M("info",`Opened ${_.id} (${C.length} files)`),Se(B,$.current.preset,$.current.options.locales)},[b,M]),S=g.useCallback((_,I)=>{const x=Y(_);v(C=>C[x]?{...C,[x]:I(C[x])}:C)},[]),O=g.useCallback((_,I,x)=>S(_,C=>({...C,drafts:{...C.drafts,[I]:x}})),[S]),V=g.useCallback((_,I,x,C=[])=>S(_,B=>{const q={...B.raw};x===null?delete q[I]:q[I]=x;const W={...B.drafts};for(const U of C)delete W[U];return{...B,raw:q,drafts:W,deleted:B.deleted.filter(U=>U!==I)}}),[S]),N=g.useCallback((_,I)=>S(_,x=>{const C={...x.raw};delete C[I];const B=!x.files.some(q=>q.path===I);return{...x,raw:C,deleted:B?x.deleted:[...new Set([...x.deleted,I])]}}),[S]),J=g.useCallback(_=>S(_,I=>({...I,raw:{},deleted:[],drafts:{}})),[S]),X=g.useCallback(async _=>{const I=$.current.provider;if(!I)return;const x=await b(`Reload ${_.id}`,()=>I.readModule(_));x&&(S(_,()=>({key:_,files:x,raw:{},deleted:[],drafts:{}})),M("info",`Reloaded ${_.id}`))},[b,S,M]),Q=g.useCallback(_=>{const I=Y(_);v(x=>{const C={...x};return delete C[I],C})},[]),K=g.useCallback(async(_,I={})=>{var le;const x=$.current.provider,C=Y(_),B=p[C];if(!x||!B)return;const q=Se(B,$.current.preset,$.current.options.locales);if(q.changes.length===0)return{ok:!0};const W=I.force?q.changes.map(Z=>({...Z,baseVersion:void 0})):q.changes,U=await b(`Save ${_.id}`,()=>x.writeModule(_,W));if(!U)return;if(!U.ok)return M("warn",`${_.id}: ${U.conflicts.length} file(s) changed meanwhile`),U;const oe=[];for(const[Z,ge]of q.pending){const me=B.files.find(se=>se.path===Z);oe.push({...me,path:Z,text:ge,version:((le=U.versions)==null?void 0:le[Z])??(me==null?void 0:me.version)})}return S(_,()=>({key:_,files:oe,raw:{},deleted:[],drafts:{}})),M("info",`Saved ${_.id}: ${W.map(Z=>`${Z.type} ${Z.path}`).join(", ")}`),U},[p,b,S,M]),T=g.useCallback(async _=>{const I=Y(_),x=h[I];if(!x)return[];const C=Ae(x,a),B=$.current.provider;let q=[];if(B!=null&&B.validate){const U=[...x.pending.entries()].map(([oe,le])=>({path:oe,text:le}));q=await b(`Validate ${_.id}`,()=>B.validate(_,U))??[]}w(U=>({...U,[I]:q}));const W=[...C,...q];M(W.some(U=>U.severity==="error")?"warn":"info",W.length===0?`${_.id}: no problems`:`${_.id}: ${W.length} problem(s)`);for(const U of W)M(U.severity==="error"?"error":U.severity==="warning"?"warn":"info",`${U.path?`${U.path}: `:""}${U.message}`);return W},[h,a,b,M]),F=g.useCallback(async _=>{const{provider:I,preset:x}=$.current;if(!(I!=null&&I.createModule)||!x.generateModule)return;const C=new Set(Object.values(i).flatMap(W=>W.map(U=>U.id))),B=await b("Generate module",()=>x.generateModule(_,{existingIds:C}));if(!B)return;const q=await b(`Create ${B.id}`,()=>I.createModule({workspaceId:_.workspaceId,packageId:B.packageId??_.packageId,id:B.id,files:B.files}));return q&&(M("info",`Created ${q.id}`),await E()),q},[i,b,M,E]),H=g.useCallback(async(_,I)=>{const{provider:x,preset:C}=$.current;if(!(x!=null&&x.createModule)||!C.duplicateModule)return;const B=await b(`Read ${_.id}`,()=>x.readModule(_));if(!B)return;const q=await b("Duplicate",()=>C.duplicateModule(B,I));if(!q)return;const W=await b(`Create ${q.id}`,()=>x.createModule({workspaceId:I.workspaceId,packageId:q.packageId??I.packageId,id:q.id,files:q.files}));return W&&(M("info",`Duplicated ${_.id} as ${W.id}`),await E()),W},[b,M,E]),G=g.useCallback(async _=>{const I=$.current.provider;if(!(I!=null&&I.deleteModule))return!1;const x=await b(`Delete ${_.id}`,async()=>(await I.deleteModule(_),!0));return x&&(Q(_),M("info",`Deleted ${_.id}`),await E()),!!x},[b,Q,M,E]),ee=g.useCallback(async _=>{const I=$.current.provider;if(!(I!=null&&I.savePackage))return;const x=await b(`Save package ${_.id}`,()=>I.savePackage(_));return x&&(M("info",`Saved package ${x.id}`),await E()),x},[b,M,E]),te=g.useCallback(async(_,I)=>{const x=$.current.provider;if(!(x!=null&&x.saveTemplate))return;const C=await b(`Save template ${_.id}`,()=>x.saveTemplate(_,I?{previousId:I}:void 0));return C&&x.listTemplates&&(d(await x.listTemplates()),M("info",`Saved template ${C.id}`)),C},[b,M]),ae=g.useCallback(async _=>{const I=$.current.provider;if(!(I!=null&&I.deleteTemplate))return!1;const x=await b(`Delete template ${_}`,async()=>(await I.deleteTemplate(_),!0));return x&&I.listTemplates&&(d(await I.listTemplates()),M("info",`Deleted template ${_}`)),!!x},[b,M]);return{workspaces:r,modulesByWs:i,packagesByWs:l,templates:m,modules:h,serverIssues:k,busy:A>0,logs:L,clearLogs:()=>j([]),log:M,refresh:E,openModule:y,close:Q,setDraft:O,setRaw:V,deleteFile:N,discard:J,reload:X,save:K,validate:T,createModule:F,duplicateModule:H,deleteModule:G,savePackage:ee,saveTemplate:te,deleteTemplate:ae}}const re="__none";function ze(t,a,o){const r=new Map((a??[]).map(u=>[u.id,u]));for(const u of o){const i=u.packageId??re;r.has(i)||r.set(i,{id:i,workspaceId:t,label:u.packageId??"",derived:!0})}return[...r.values()].sort((u,i)=>u.id===re?1:i.id===re?-1:u.label.localeCompare(i.label))}function Tt({session:t,provider:a,canCreateModule:o,canDuplicateModule:r,issueCounts:u,actions:i,defaultTab:s,readOnly:l}){var E;const{t:n}=c.useNiceTranslation(),[m,d]=g.useState(a!=null&&a.listTemplates?s:"modules"),[p,v]=g.useState(null),k=n("devStudio.explorer.noPackage","No package"),w=g.useMemo(()=>t.workspaces.map(h=>{const y=t.modulesByWs[h.id]??[];return{id:`w:${h.id}`,kind:"workspace",label:h.label,icon:h.icon??"folder",info:String(y.length),workspaceId:h.id,readOnly:h.readOnly,children:ze(h.id,t.packagesByWs[h.id],y).map(S=>({id:`w:${h.id}/p:${S.id}`,kind:"package",label:S.id===re?k:S.label||S.id,icon:S.icon??"archive",workspaceId:h.id,packageId:S.id===re?void 0:S.id,children:y.filter(O=>(O.packageId??re)===S.id).sort((O,V)=>O.label.localeCompare(V.label)).map(O=>{const V=Y(O),N=t.modules[V];return{id:`w:${h.id}/p:${S.id}/m:${O.id}`,kind:"module",label:O.label,icon:O.icon&&/^[a-z0-9-]+$/.test(O.icon)?O.icon:"box",info:O.version??(N?String(N.working.length):O.files?String(O.files.length):void 0),workspaceId:h.id,packageId:O.packageId,moduleId:O.id,readOnly:O.readOnly,shadowedBy:O.shadowedBy,dirty:N==null?void 0:N.dirty,issues:u[V],search:`${O.id} ${O.description??""} ${O.search??""}`,children:N==null?void 0:N.documents.map(J=>({id:`w:${h.id}/p:${S.id}/m:${O.id}/d:${J.key}`,kind:"document",label:J.label,icon:J.kind.icon??"file",info:J.paths.length>1?String(J.paths.length):void 0,workspaceId:h.id,moduleId:O.id,docKey:J.key,dirty:J.key in N.drafts||J.paths.some(X=>X in N.raw),search:J.paths.join(" ")}))}})}))}}),[t.workspaces,t.modulesByWs,t.packagesByWs,t.modules,u,k]),A=g.useMemo(()=>{const h=new Map;for(const y of Object.values(t.modulesByWs))for(const S of y)h.has(S.id)||h.set(S.id,S);return h},[t.modulesByWs]),R=g.useMemo(()=>{const h=new Map;for(const S of t.templates??[]){const O=S.category??"";h.set(O,[...h.get(O)??[],S])}const y=S=>{var O,V;return((O=S.translations.en)==null?void 0:O.name)??((V=Object.values(S.translations)[0])==null?void 0:V.name)??S.id};return[...h.entries()].sort(([S],[O])=>S.localeCompare(O)).map(([S,O])=>({id:`c:${S}`,kind:"category",label:S||n("devStudio.explorer.noCategory","Other"),icon:"folder",info:String(O.length),children:O.sort((V,N)=>(V.sortOrder??0)-(N.sortOrder??0)||y(V).localeCompare(y(N))).map(V=>({id:`c:${S}/t:${V.id}`,kind:"template",label:y(V),icon:V.icon&&/^[a-z0-9-]+$/.test(V.icon)?V.icon:"layers",info:String(V.modules.length),templateId:V.id,search:`${V.id} ${(V.tags??[]).join(" ")}`,children:V.modules.map(N=>{const J=A.get(N.moduleId);return{id:`c:${S}/t:${V.id}/m:${N.moduleId}`,kind:"templateModule",label:(J==null?void 0:J.label)??N.moduleId,icon:"box",info:N.required?n("devStudio.template.required","required"):void 0,templateId:V.id,moduleId:N.moduleId,workspaceId:J==null?void 0:J.workspaceId,missing:!J}})}))}))},[t.templates,A,n]),L=g.useMemo(()=>[{field:"label",header:n("devStudio.explorer.name","Name"),render:(h,y)=>e.jsxs("span",{className:"nice-development-studio__tree-name",children:[e.jsx(c.NiceIcon,{name:y.icon,size:14}),e.jsx("span",{className:y.missing?"nice-development-studio__missing":void 0,children:y.label}),y.dirty&&e.jsx("span",{className:"nice-development-studio__dot",title:n("devStudio.explorer.unsaved","Unsaved changes"),children:e.jsx(c.NiceIcon,{name:"circle",size:8})}),!!y.issues&&e.jsx("span",{className:"nice-development-studio__badge",title:n("devStudio.explorer.problems","Problems"),children:y.issues}),y.readOnly&&e.jsx("span",{title:n("devStudio.explorer.readOnly","Read-only"),children:e.jsx(c.NiceIcon,{name:"lock",size:12})}),y.shadowedBy&&e.jsx("span",{className:"nice-development-studio__tag",title:y.shadowedBy,children:n("devStudio.explorer.shadowed","shadowed")}),y.missing&&e.jsx("span",{className:"nice-development-studio__tag",children:n("devStudio.explorer.missing","missing")})]})},{field:"info",header:"",width:64,align:"right"}],[n]),j=h=>h.workspaceId&&h.moduleId?{workspaceId:h.workspaceId,id:h.moduleId}:null,$=h=>{v(h);const y=j(h);if(h.kind==="module"&&y)i.openModule(y);else if(h.kind==="document"&&y&&h.docKey)i.openDocument(y,h.docKey);else if(h.kind==="package"&&h.workspaceId){const S=ze(h.workspaceId,t.packagesByWs[h.workspaceId],t.modulesByWs[h.workspaceId]??[]).find(O=>(O.id===re?void 0:O.id)===h.packageId);S&&S.id!==re&&i.openPackage(S)}else h.kind==="template"&&h.templateId?i.openTemplate(h.templateId):h.kind==="templateModule"&&y&&i.openModule(y)},M=p&&(p.kind==="module"||p.kind==="templateModule")?j(p):null,b=h=>{var y;return!l&&!!h&&!((y=t.workspaces.find(S=>S.id===h))!=null&&y.readOnly)};return e.jsxs("div",{className:"nice-development-studio__explorer","data-tour":"devstudio-explorer",children:[(a==null?void 0:a.listTemplates)&&e.jsxs("div",{className:"nice-development-studio__segmented",role:"group","aria-label":n("devStudio.explorer.show","Show"),children:[e.jsx(c.NiceButton,{size:"sm",variant:m==="modules"?"primary":"ghost","aria-pressed":m==="modules",onClick:()=>d("modules"),children:n("devStudio.explorer.modules","Modules")}),e.jsx(c.NiceButton,{size:"sm",variant:m==="templates"?"primary":"ghost","aria-pressed":m==="templates",onClick:()=>d("templates"),children:n("devStudio.explorer.templates","Templates")})]}),e.jsxs("div",{className:"nice-development-studio__explorer-actions",children:[e.jsx(c.NiceButton,{size:"sm",variant:"ghost",ariaLabel:n("devStudio.refresh","Refresh"),onClick:()=>void t.refresh(),children:e.jsx(c.NiceIcon,{name:"refresh",size:14})}),m==="modules"&&o&&!l&&e.jsx(c.NiceButton,{size:"sm",variant:"ghost",leftIcon:e.jsx(c.NiceIcon,{name:"plus",size:14}),onClick:()=>i.newModule({workspaceId:p==null?void 0:p.workspaceId,packageId:p==null?void 0:p.packageId}),children:n("devStudio.explorer.newModule","Module")}),m==="modules"&&(a==null?void 0:a.savePackage)&&!l&&e.jsx(c.NiceButton,{size:"sm",variant:"ghost",leftIcon:e.jsx(c.NiceIcon,{name:"plus",size:14}),disabled:!b((p==null?void 0:p.workspaceId)??((E=t.workspaces.find(h=>!h.readOnly))==null?void 0:E.id)),onClick:()=>{var h;return i.newPackage((p==null?void 0:p.workspaceId)??((h=t.workspaces.find(y=>!y.readOnly))==null?void 0:h.id)??"")},children:n("devStudio.explorer.newPackage","Package")}),m==="templates"&&(a==null?void 0:a.saveTemplate)&&!l&&e.jsx(c.NiceButton,{size:"sm",variant:"ghost",leftIcon:e.jsx(c.NiceIcon,{name:"plus",size:14}),onClick:()=>i.newTemplate(),children:n("devStudio.explorer.newTemplate","Template")}),M&&e.jsxs(e.Fragment,{children:[e.jsx(c.NiceButton,{size:"sm",variant:"ghost",ariaLabel:n("devStudio.validate","Validate"),onClick:()=>i.validateModule(M),children:e.jsx(c.NiceIcon,{name:"check",size:14})}),(a==null?void 0:a.saveTemplate)&&!l&&e.jsx(c.NiceButton,{size:"sm",variant:"ghost",ariaLabel:n("devStudio.explorer.addToTemplate","Add to template"),onClick:()=>i.addToTemplate(M),children:e.jsx(c.NiceIcon,{name:"layers",size:14})}),r&&!l&&e.jsx(c.NiceButton,{size:"sm",variant:"ghost",ariaLabel:n("devStudio.explorer.duplicate","Duplicate"),onClick:()=>i.duplicateModule(M),children:e.jsx(c.NiceIcon,{name:"copy",size:14})}),(a==null?void 0:a.deleteModule)&&b(M.workspaceId)&&!(p!=null&&p.readOnly)&&e.jsx(c.NiceButton,{size:"sm",variant:"ghost",ariaLabel:n("devStudio.delete","Delete"),onClick:()=>i.deleteModule(M),children:e.jsx(c.NiceIcon,{name:"trash",size:14})})]})]}),e.jsx("div",{className:"nice-development-studio__tree",children:m==="modules"?e.jsx(c.NiceTreeGrid,{data:w,nested:!0,keyField:"id",childrenField:"children",columns:L,sortable:!1,compact:!0,searchable:!0,searchFields:["label","search"],searchPlaceholder:n("devStudio.explorer.search","Search modules and files"),toolbarActions:["collapseAll"],defaultExpandedKeys:t.workspaces.map(h=>`w:${h.id}`),hasChildren:h=>h.kind==="module",loadChildren:async h=>{const y=j(h);return y&&!t.modules[Y(y)]&&await t.openModule(y),[]},onRowClick:$,rowClassName:h=>(p==null?void 0:p.id)===h.id?"nice-development-studio__tree-row--selected":void 0,emptyText:n("devStudio.explorer.empty","No modules."),"aria-label":n("devStudio.explorer.modules","Modules"),"data-testid":"studio-modules-tree"},"modules"):e.jsx(c.NiceTreeGrid,{data:R,nested:!0,keyField:"id",childrenField:"children",columns:L,sortable:!1,compact:!0,searchable:!0,searchFields:["label","search"],searchPlaceholder:n("devStudio.explorer.searchTemplates","Search templates"),onRowClick:$,rowClassName:h=>(p==null?void 0:p.id)===h.id?"nice-development-studio__tree-row--selected":void 0,emptyText:n("devStudio.explorer.noTemplates","No templates."),"aria-label":n("devStudio.explorer.templates","Templates"),"data-testid":"studio-templates-tree"},"templates")})]})}function Ct({module:t,moduleRef:a,session:o,provider:r,preset:u,issues:i,readOnly:s,panels:l,onOpenDocument:n,onSave:m}){const{t:d}=c.useNiceTranslation(),p=j=>j.labelKey?d(j.labelKey,j.label):j.label,[v,k]=g.useState(null),w=t.key;g.useEffect(()=>{let j=!0;return r!=null&&r.listRevisions&&r.listRevisions(w).then($=>{j&&k($.map(M=>({id:M.id,label:M.label,author:M.author,timestamp:M.timestamp,summary:M.summary})))}).catch(()=>k([])),()=>{j=!1}},[r,w,t.files]);const A=j=>t.documents.find($=>j&&$.paths.includes(j)),R=u.newFile?u.kinds.filter(j=>{var M;const $=(M=u.newFile)==null?void 0:M.call(u,j.id,{key:w,files:t.working,documents:t.documents});return!!$&&!t.working.some(b=>b.path===$.path)}):[],L=[{id:"documents",label:`${d("devStudio.overview.documents","Documents")} (${t.documents.length})`,content:e.jsx("ul",{className:"nice-development-studio__list",children:t.documents.map(j=>e.jsxs("li",{children:[e.jsx(c.NiceButton,{size:"sm",variant:"ghost",leftIcon:e.jsx(c.NiceIcon,{name:j.kind.icon??"file",size:14}),onClick:()=>n(j.key),children:j.label}),e.jsx("span",{className:"nice-development-studio__muted",children:p(j.kind)}),(j.key in t.drafts||j.paths.some($=>$ in t.raw))&&e.jsx("span",{className:"nice-development-studio__tag",children:d("devStudio.explorer.unsaved","Unsaved changes")})]},j.key))})},{id:"problems",label:`${d("devStudio.overview.problems","Problems")} (${i.length})`,content:i.length===0?e.jsx("p",{className:"nice-development-studio__muted",children:d("devStudio.overview.noProblems","No problems found.")}):e.jsx("ul",{className:"nice-development-studio__issues",children:i.map((j,$)=>{const M=A(j.path),b=j.messageKey?Object.entries(j.params??{}).reduce((E,[h,y])=>E.replace(`{${h}}`,String(y)),d(j.messageKey,j.message)):j.message;return e.jsxs("li",{className:`nice-development-studio__issue nice-development-studio__issue--${j.severity}`,children:[e.jsx(c.NiceIcon,{name:j.severity==="error"?"error":j.severity==="warning"?"warning":"info",size:14}),M?e.jsx(c.NiceButton,{size:"sm",variant:"ghost",onClick:()=>n(M.key),children:j.path}):j.path&&e.jsx("span",{className:"nice-development-studio__muted",children:j.path}),e.jsx("span",{children:b})]},$)})})},...r!=null&&r.listRevisions?[{id:"history",label:d("devStudio.overview.history","History"),content:e.jsx(c.NiceRevisionHistory,{revisions:v??[],language:"json",loadContent:r.readRevision?j=>r.readRevision(w,j):void 0,onRollback:r.rollback&&!s?async j=>{await r.rollback(w,j),await o.reload(w)}:void 0})}]:[],...l.map(j=>({id:`panel:${j.key}`,label:j.label,content:j.content}))];return e.jsxs("div",{className:"nice-development-studio__overview","data-testid":"studio-module-overview",children:[e.jsxs("div",{className:"nice-development-studio__doc-bar",children:[e.jsx(c.NiceIcon,{name:"box",size:16}),e.jsx("strong",{className:"nice-development-studio__doc-title",children:(a==null?void 0:a.label)??w.id}),e.jsx("span",{className:"nice-development-studio__muted",children:(a==null?void 0:a.location)??w.id}),(a==null?void 0:a.readOnly)&&e.jsx("span",{className:"nice-development-studio__tag",children:d("devStudio.explorer.readOnly","Read-only")}),(a==null?void 0:a.shadowedBy)&&e.jsx("span",{className:"nice-development-studio__tag",title:a.shadowedBy,children:d("devStudio.explorer.shadowed","shadowed")}),e.jsx("span",{className:"nice-development-studio__spacer"}),e.jsx(c.NiceButton,{size:"sm",variant:"ghost",leftIcon:e.jsx(c.NiceIcon,{name:"check",size:14}),onClick:()=>void o.validate(w),"data-tour":"devstudio-validate",children:d("devStudio.validate","Validate")}),e.jsx(c.NiceButton,{size:"sm",variant:"ghost",leftIcon:e.jsx(c.NiceIcon,{name:"refresh",size:14}),onClick:()=>void o.reload(w),children:d("devStudio.reload","Reload")}),!s&&e.jsxs(e.Fragment,{children:[e.jsx(c.NiceButton,{size:"sm",variant:"ghost",disabled:!t.dirty,onClick:()=>o.discard(w),children:d("devStudio.discard","Discard changes")}),e.jsx(c.NiceButton,{size:"sm",variant:"primary",disabled:!t.dirty,onClick:m,"data-tour":"devstudio-save",children:t.dirty?d("devStudio.saveCount","Save ({count})").replace("{count}",String(t.changes.length)):d("devStudio.save","Save")})]})]}),!s&&R.length>0&&e.jsxs("div",{className:"nice-development-studio__row",children:[e.jsx("span",{className:"nice-development-studio__muted",children:d("devStudio.overview.newFile","New file:")}),R.map(j=>e.jsx(c.NiceButton,{size:"sm",variant:"ghost",leftIcon:e.jsx(c.NiceIcon,{name:j.icon??"file",size:14}),onClick:()=>{var M;const $=(M=u.newFile)==null?void 0:M.call(u,j.id,{key:w,files:t.working,documents:t.documents});$&&!t.working.some(b=>b.path===$.path)&&o.setRaw(w,$.path,$.text)},children:p(j)},j.id))]}),e.jsx(c.NiceTabs,{tabs:L})]})}const Et=t=>({type:"object",required:["id"],properties:{id:{type:"string",title:t("devStudio.template.id","Id (slug)")},category:{type:"string",title:t("devStudio.template.category","Category")},subCategory:{type:"string",title:t("devStudio.template.subCategory","Subcategory")},parentId:{type:"string",title:t("devStudio.template.parent","Parent template")},icon:{type:"string",title:t("devStudio.template.icon","Icon")},sortOrder:{type:"number",title:t("devStudio.template.sortOrder","Order")},tags:{type:"array",items:{type:"string"},title:t("devStudio.template.tags","Tags")}}});function Mt({session:t,template:a,locales:o,extraSchema:r,readOnly:u,onSaved:i,onDeleted:s}){var M;const{t:l}=c.useNiceTranslation(),[n,m]=g.useState(()=>a??{id:"",translations:{[o[0]??"en"]:{name:""}},modules:[]}),[d,p]=g.useState(null),v=u||!!(a!=null&&a.readOnly),k={id:n.id,category:n.category,subCategory:n.subCategory,parentId:n.parentId,icon:n.icon,sortOrder:n.sortOrder,tags:n.tags},w=Object.fromEntries(Object.entries(n.translations).map(([b,E])=>[b,{name:E.name,description:E.description??""}])),A=g.useMemo(()=>t.workspaces.map(b=>{const E=t.modulesByWs[b.id]??[],h=[...new Set(E.map(y=>y.packageId??""))].sort();return{id:`w:${b.id}`,label:b.label,kind:"workspace",children:h.map(y=>({id:`w:${b.id}/p:${y}`,label:y||l("devStudio.explorer.noPackage","No package"),kind:"package",children:E.filter(S=>(S.packageId??"")===y).map(S=>({id:`m:${S.id}`,label:S.label,kind:"module"}))}))}}),[t.workspaces,t.modulesByWs,l]),R=g.useMemo(()=>{const b=new Map;for(const E of Object.values(t.modulesByWs))for(const h of E)b.set(h.id,h.label);return b},[t.modulesByWs]),L=b=>m({...n,modules:b}),j=(b,E)=>{const h=[...n.modules],[y]=h.splice(b,1);h.splice(b+E,0,y),L(h)},$=[{field:"label",header:l("devStudio.explorer.name","Name")}];return e.jsxs("div",{className:"nice-development-studio__template","data-testid":"studio-template-editor",children:[e.jsxs("div",{className:"nice-development-studio__doc-bar",children:[e.jsx(c.NiceIcon,{name:"layers",size:14}),e.jsx("strong",{className:"nice-development-studio__doc-title",children:a?((M=n.translations.en)==null?void 0:M.name)||n.id:l("devStudio.template.new","New template")}),e.jsx("span",{className:"nice-development-studio__spacer"}),!v&&e.jsx(c.NiceButton,{size:"sm",variant:"primary",disabled:!n.id.trim(),onClick:async()=>{p(null);const b=await t.saveTemplate({...n,id:n.id.trim()},a==null?void 0:a.id);b?i==null||i(b):p(l("devStudio.template.saveFailed","The template could not be saved; see the output panel."))},children:l("devStudio.save","Save")}),!v&&a&&e.jsx(c.NiceButton,{size:"sm",variant:"ghost",leftIcon:e.jsx(c.NiceIcon,{name:"trash",size:14}),onClick:async()=>{await t.deleteTemplate(a.id)&&(s==null||s())},children:l("devStudio.delete","Delete")})]}),d&&e.jsx("p",{className:"nice-development-studio__error",role:"alert",children:d}),e.jsxs("div",{className:"nice-development-studio__columns",children:[e.jsxs("section",{children:[e.jsx("h4",{children:l("devStudio.template.basics","Template")}),e.jsx(pe,{schema:Et(l),value:k,readOnly:v,onChange:b=>m({...n,id:String(b.id??""),category:b.category||void 0,subCategory:b.subCategory||void 0,parentId:b.parentId||void 0,icon:b.icon||void 0,sortOrder:typeof b.sortOrder=="number"?b.sortOrder:void 0,tags:Array.isArray(b.tags)?b.tags:void 0})}),r&&e.jsx(pe,{schema:r,value:n.extra??{},readOnly:v,onChange:b=>m({...n,extra:b})}),e.jsx("h4",{children:l("devStudio.template.translations","Name and description")}),e.jsx(Ce,{value:w,locales:[...new Set([...o,...Object.keys(w)])],allowEditLocales:!0,readOnly:v,onChange:b=>m({...n,translations:Object.fromEntries(Object.entries(b).map(([E,h])=>[E,{name:h.name??"",...h.description?{description:h.description}:{}}]))})})]}),e.jsxs("section",{children:[e.jsx("h4",{children:l("devStudio.template.modules","Modules")}),e.jsx(c.NiceTreeGrid,{data:A,nested:!0,keyField:"id",childrenField:"children",columns:$,sortable:!1,compact:!0,checkable:!0,checkStrategy:"leaves",isRowCheckable:b=>b.kind!=="workspace",isRowDisabled:()=>v,checkedKeys:n.modules.map(b=>`m:${b.moduleId}`),onCheckedChange:b=>{const E=b.filter(S=>S.startsWith("m:")).map(S=>S.slice(2)),h=n.modules.filter(S=>E.includes(S.moduleId)),y=E.filter(S=>!h.some(O=>O.moduleId===S)).map(S=>({moduleId:S}));L([...h,...y])},checkedSummary:b=>l("devStudio.template.summary","{count} modules · {required} required").replace("{count}",String(b.checked)).replace("{required}",String(n.modules.filter(E=>E.required).length)),searchable:!0,searchFields:["label"],virtualScroll:!0,height:320,"aria-label":l("devStudio.template.modules","Modules")}),e.jsxs("table",{className:"nice-development-studio__table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:l("devStudio.template.module","Module")}),e.jsx("th",{children:l("devStudio.template.required","required")}),e.jsx("th",{children:l("devStudio.template.condition","Condition")}),!v&&e.jsx("th",{"aria-label":l("devStudio.template.order","Order")})]})}),e.jsx("tbody",{children:n.modules.map((b,E)=>e.jsxs("tr",{children:[e.jsx("td",{children:R.get(b.moduleId)??b.moduleId}),e.jsx("td",{children:e.jsx("input",{type:"checkbox",checked:!!b.required,disabled:v,"aria-label":`${l("devStudio.template.required","required")} ${b.moduleId}`,onChange:h=>L(n.modules.map((y,S)=>S===E?{...y,required:h.target.checked}:y))})}),e.jsx("td",{children:e.jsx("input",{className:"nice-development-studio__cell",value:b.condition??"",readOnly:v,"aria-label":`${l("devStudio.template.condition","Condition")} ${b.moduleId}`,onChange:h=>L(n.modules.map((y,S)=>S===E?{...y,condition:h.target.value||void 0}:y))})}),!v&&e.jsxs("td",{className:"nice-development-studio__nowrap",children:[e.jsx(c.NiceButton,{size:"sm",variant:"ghost",disabled:E===0,ariaLabel:l("devStudio.template.up","Move up"),onClick:()=>j(E,-1),children:e.jsx(c.NiceIcon,{name:"chevron-up",size:12})}),e.jsx(c.NiceButton,{size:"sm",variant:"ghost",disabled:E===n.modules.length-1,ariaLabel:l("devStudio.template.down","Move down"),onClick:()=>j(E,1),children:e.jsx(c.NiceIcon,{name:"chevron-down",size:12})})]})]},b.moduleId))})]})]})]})]})}function $t({session:t,pkg:a,readOnly:o,onNewModule:r,onOpenModule:u}){const{t:i}=c.useNiceTranslation(),[s,l]=g.useState({id:a.id,label:a.label,description:a.description,icon:a.icon}),n=(t.modulesByWs[a.workspaceId]??[]).filter(d=>d.packageId===a.id),m=!o&&!a.derived&&!a.readOnly;return e.jsxs("div",{className:"nice-development-studio__template","data-testid":"studio-package-editor",children:[e.jsxs("div",{className:"nice-development-studio__doc-bar",children:[e.jsx(c.NiceIcon,{name:"archive",size:14}),e.jsx("strong",{className:"nice-development-studio__doc-title",children:a.label||a.id}),e.jsx("span",{className:"nice-development-studio__spacer"}),!o&&e.jsx(c.NiceButton,{size:"sm",variant:"ghost",leftIcon:e.jsx(c.NiceIcon,{name:"plus",size:14}),onClick:r,children:i("devStudio.package.newModule","New module here")}),m&&e.jsx(c.NiceButton,{size:"sm",variant:"primary",onClick:()=>void t.savePackage({...a,id:String(s.id??a.id),label:String(s.label??""),description:s.description||void 0,icon:s.icon||void 0}),children:i("devStudio.save","Save")})]}),a.derived?e.jsx("p",{className:"nice-development-studio__muted",children:i("devStudio.package.derived","This package comes from the modules themselves (their category); rename it by changing their manifests.")}):e.jsx(pe,{schema:{type:"object",required:["id","label"],properties:{id:{type:"string",title:i("devStudio.package.id","Id")},label:{type:"string",title:i("devStudio.package.label","Name")},description:{type:"string",title:i("devStudio.package.description","Description")},icon:{type:"string",title:i("devStudio.template.icon","Icon")}}},value:s,readOnly:!m,onChange:d=>l(d)}),e.jsx("h4",{children:i("devStudio.template.modules","Modules")}),e.jsxs("ul",{className:"nice-development-studio__list",children:[n.map(d=>e.jsxs("li",{children:[e.jsx(c.NiceButton,{size:"sm",variant:"ghost",leftIcon:e.jsx(c.NiceIcon,{name:"box",size:14}),onClick:()=>u(d.id),children:d.label}),d.description&&e.jsx("span",{className:"nice-development-studio__muted",children:d.description})]},d.id)),n.length===0&&e.jsx("li",{className:"nice-development-studio__muted",children:i("devStudio.explorer.empty","No modules.")})]})]})}const Ft=[{target:".nice-development-studio",titleKey:"tutorial.devStudio.intro.title",title:"Development studio",contentKey:"tutorial.devStudio.intro.content",content:"Design whole modules: their manifest, entities, translations, views, workflows, permissions, data sources and seeds. Saving writes back only what changed.",placement:"auto"},{target:'[data-tour="devstudio-explorer"]',titleKey:"tutorial.devStudio.explorer.title",title:"Projects, packages and modules",contentKey:"tutorial.devStudio.explorer.content",content:"Browse projects, their packages and modules. Expand a module to see its files; switch to Templates to manage the module sets installed together.",placement:"right"},{target:".nice-development-studio .nice-console__tabs",titleKey:"tutorial.devStudio.tabs.title",title:"Open documents",contentKey:"tutorial.devStudio.tabs.content",content:"Each file opens in its own editor. Use Source to edit the raw text and Changes to see what saving writes.",placement:"bottom"},{target:'[data-tour="devstudio-save"]',titleKey:"tutorial.devStudio.save.title",title:"Validate and save",contentKey:"tutorial.devStudio.save.content",content:"Check the module, review the changed files and save them — only the bytes you changed are written.",placement:"bottom"},{target:'[data-tour="devstudio-output"]',titleKey:"tutorial.devStudio.output.title",title:"Output",contentKey:"tutorial.devStudio.output.content",content:"Loading, saving and validation are logged here.",placement:"top"}],Ot=["en","pl","de","fr","es","uk"],zt=g.forwardRef(function(a,o){const{provider:r,preset:u,defaultModule:i,defaultExplorerTab:s="modules",onModuleOpen:l,onSaved:n,onError:m,reviewBeforeSave:d=!0,scriptRunner:p,renderViewPreview:v,modulePanels:k,readOnly:w=!1,theme:A="light",height:R=720,explorerWidth:L=300,tutorial:j,className:$,style:M,id:b,testId:E,"data-testid":h}=a,{t:y}=c.useNiceTranslation(),S=g.useRef(null);g.useImperativeHandle(o,()=>S.current);const O=g.useMemo(()=>typeof u=="function"?u(y):u??P.nativeStudioPreset,[u,y]),V=g.useMemo(()=>O.locales??Ot,[O]),N=It(r,O,{locales:V,onError:m}),[J,X]=g.useState([]),[Q,K]=g.useState(""),[T,F]=g.useState(null),[H,G]=g.useState(0),ee=g.useCallback(f=>{var z;return(z=N.modulesByWs[f.workspaceId])==null?void 0:z.find(D=>D.id===f.id)},[N.modulesByWs]),te=f=>{var z;return((z=ee(f))==null?void 0:z.label)??f.id},ae=g.useMemo(()=>{const f={};for(const[z,D]of Object.entries(N.modules))f[z]=[...Ae(D,O),...N.serverIssues[z]??[]];return f},[N.modules,N.serverIssues,O]),_=g.useMemo(()=>Object.fromEntries(Object.entries(ae).map(([f,z])=>[f,z.filter(D=>D.severity==="error").length])),[ae]),I=g.useCallback(f=>{X(z=>z.some(D=>D.key===f.key)?z:[...z,f]),K(f.key)},[]),x=g.useCallback(async f=>{N.modules[Y(f)]||await N.openModule(f),I({key:`o:${Y(f)}`,kind:"overview",module:f}),l==null||l(f)},[N,I,l]),C=g.useCallback(async(f,z)=>{N.modules[Y(f)]||await N.openModule(f),I({key:`d:${Y(f)}::${z}`,kind:"document",module:f,docKey:z})},[N,I]),B=g.useRef(!1);g.useEffect(()=>{i&&!B.current&&N.modulesByWs[i.workspaceId]&&(B.current=!0,x(i))},[i,N.modulesByWs,x]);const q=J.find(f=>f.key===Q),W=q&&"module"in q?q.module:void 0,U=g.useCallback(async f=>{const z=N.modules[Y(f)];if(!(z!=null&&z.dirty)||w)return;if(d){F({kind:"review",module:f});return}const D=await N.save(f);D&&!D.ok?F({kind:"review",module:f,conflict:D}):D!=null&&D.ok&&(n==null||n(f,D))},[N,w,d,n]),oe=g.useRef(()=>{});oe.current=()=>{W&&U(W)},g.useEffect(()=>{const f=S.current;if(!f)return;const z=D=>{(D.ctrlKey||D.metaKey)&&!D.altKey&&D.key.toLowerCase()==="s"&&(D.preventDefault(),oe.current())};return f.addEventListener("keydown",z),()=>f.removeEventListener("keydown",z)},[]);const le=f=>{X(z=>{var ie;const D=z.filter(ce=>ce.key!==f);return Q===f&&K(((ie=D[D.length-1])==null?void 0:ie.key)??""),D})},Z=N.workspaces.filter(f=>!f.readOnly).map(f=>({id:f.id,label:f.label})),ge=f=>{var he;if(f.kind==="package")return e.jsx($t,{session:N,pkg:f.pkg,readOnly:w,onNewModule:()=>F({kind:"wizard",prefill:{workspaceId:f.pkg.workspaceId,packageId:f.pkg.id}}),onOpenModule:ne=>void x({workspaceId:f.pkg.workspaceId,id:ne})});if(f.kind==="template"){const ne=f.templateId?(he=N.templates)==null?void 0:he.find(de=>de.id===f.templateId):void 0;return e.jsx(Mt,{session:N,template:ne,locales:V,extraSchema:O.templateSchema,readOnly:w,onSaved:de=>{(!f.templateId||de.id!==f.templateId)&&(le(f.key),I({key:`t:${de.id}`,kind:"template",templateId:de.id}))},onDeleted:()=>le(f.key)},f.key)}const z=N.modules[Y(f.module)];if(!z)return e.jsx("p",{className:"nice-development-studio__muted",children:y("devStudio.loading","Loading…")});const D=ee(f.module),ie=w||!!(D!=null&&D.readOnly);if(f.kind==="overview")return e.jsx(Ct,{module:z,moduleRef:D,session:N,provider:r,preset:O,issues:ae[Y(f.module)]??[],readOnly:ie,panels:(k==null?void 0:k({module:f.module,files:z.working,dirty:z.dirty}))??[],onOpenDocument:ne=>void C(f.module,ne),onSave:()=>void U(f.module)});const ce=z.documents.find(ne=>ne.key===f.docKey);return ce?e.jsx(xt,{module:z,doc:ce,preset:O,session:N,locales:V,readOnly:ie,scriptRunner:p,renderViewPreview:v},f.key):e.jsx("p",{className:"nice-development-studio__muted",children:y("devStudio.doc.gone","This file is no longer in the module.")})},me=J.map(f=>{var he,ne,de;const z="module"in f?N.modules[Y(f.module)]:void 0,D=f.kind==="document"?z==null?void 0:z.documents.find(fe=>fe.key===f.docKey):void 0,ie=f.kind==="overview"?!!(z!=null&&z.dirty):f.kind==="document"&&D&&z?D.key in z.drafts||D.paths.some(fe=>fe in z.raw):!1,ce=f.kind==="overview"?te(f.module):f.kind==="document"?(D==null?void 0:D.label)??f.docKey:f.kind==="package"?f.pkg.label||f.pkg.id:f.templateId?((de=(ne=(he=N.templates)==null?void 0:he.find(fe=>fe.id===f.templateId))==null?void 0:ne.translations.en)==null?void 0:de.name)??f.templateId:y("devStudio.template.new","New template");return{key:f.key,label:ie?`${ce} •`:ce,closable:!0,icon:e.jsx(c.NiceIcon,{name:f.kind==="overview"?"box":f.kind==="package"?"archive":f.kind==="template"?"layers":(D==null?void 0:D.kind.icon)??"file",size:14}),render:()=>ge(f)}}),se=W?N.modules[Y(W)]:void 0,ye=W?ae[Y(W)]??[]:[],qe=[...W?[{key:"module",position:"left",label:te(W)},{key:"dirty",position:"left",label:se!=null&&se.dirty?y("devStudio.status.changed","{count} changed files").replace("{count}",String(se.changes.length)):y("devStudio.status.saved","Saved")},{key:"issues",position:"left",label:e.jsxs("span",{className:"nice-development-studio__status",children:[e.jsx(c.NiceIcon,{name:ye.length===0?"check":"warning",size:12}),ye.length===0?y("devStudio.status.valid","No problems"):y("devStudio.status.problems","{count} problems").replace("{count}",String(ye.length))]}),onClick:()=>W&&I({key:`o:${Y(W)}`,kind:"overview",module:W})}]:[],...N.busy?[{key:"busy",position:"right",label:y("devStudio.loading","Loading…")}]:[]],Re=[{key:"save",label:y("devStudio.save","Save"),shortcut:"Ctrl+S",disabled:!(se!=null&&se.dirty)||w},{key:"validate",label:y("devStudio.validate","Validate"),disabled:!W},{key:"refresh",label:y("devStudio.refresh","Refresh")},...r!=null&&r.createModule&&O.generateModule&&!w?[{key:"newModule",label:y("devStudio.explorer.newModule","Module")}]:[]],xe=(T==null?void 0:T.kind)==="review"?N.modules[Y(T.module)]:void 0,Ve=`nice-development-studio${$?` ${$}`:""}`;return e.jsxs("div",{ref:S,id:b,className:Ve,style:{height:R,...M},"data-testid":h??E,children:[e.jsx(c.NiceConsole,{className:"nice-development-studio__console",style:{height:"100%"},theme:A,tabs:me,activeTabKey:Q,onTabChange:K,onTabClose:le,commandPalette:Re,onCommand:f=>{f==="save"?oe.current():f==="validate"&&W?N.validate(W):f==="refresh"?N.refresh():f==="newModule"&&F({kind:"wizard",prefill:{}})},toolbar:e.jsxs("div",{className:"nice-development-studio__toolbar",children:[e.jsx("strong",{children:y("devStudio.title","Development studio")}),j&&e.jsx(c.NiceTutorialButton,{steps:c.resolveTutorial(j,Ft)})]}),sidePanel:e.jsx(Tt,{session:N,provider:r,canCreateModule:!!(r!=null&&r.createModule)&&!!O.generateModule,canDuplicateModule:!!(r!=null&&r.createModule)&&!!O.duplicateModule,issueCounts:_,defaultTab:s,readOnly:w,actions:{openModule:f=>void x(f),openDocument:(f,z)=>void C(f,z),openPackage:f=>I({key:`p:${f.workspaceId}/${f.id}`,kind:"package",pkg:f}),openTemplate:f=>I({key:`t:${f}`,kind:"template",templateId:f}),newModule:f=>F({kind:"wizard",prefill:f}),newPackage:f=>F({kind:"package",workspaceId:f}),newTemplate:()=>{G(f=>f+1),I({key:`t:new:${H+1}`,kind:"template",templateId:null})},duplicateModule:f=>F({kind:"duplicate",module:f}),deleteModule:f=>F({kind:"delete",module:f}),addToTemplate:f=>F({kind:"templates",module:f}),validateModule:f=>{(async()=>(N.modules[Y(f)]||await N.openModule(f),await N.validate(f)))()}}}),sidePanelWidth:L,bottomPanelHeight:120,statusItems:qe,bottomPanel:e.jsx("div",{"data-tour":"devstudio-output",className:"nice-development-studio__output",children:e.jsx(c.NiceLogConsole,{title:y("devStudio.output","Output"),entries:N.logs,onClear:N.clearLogs,maxHeight:"100%"})}),children:e.jsx("div",{className:"nice-development-studio__placeholder",children:r?y("devStudio.placeholder","Open a module, a package or a template from the explorer."):y("devStudio.noProvider","Connect a provider to browse modules.")})}),(T==null?void 0:T.kind)==="wizard"&&e.jsx(ht,{open:!0,onClose:()=>F(null),session:N,preset:O,locales:V,prefill:T.prefill,onCreated:f=>void x(f)}),(T==null?void 0:T.kind)==="review"&&xe&&e.jsx(ft,{open:!0,moduleLabel:te(T.module),changes:xe.changes,original:f=>{var z;return((z=xe.files.find(D=>D.path===f))==null?void 0:z.text)??""},conflict:T.conflict,onClose:()=>F(null),onSave:async()=>{const f=await N.save(T.module);f!=null&&f.ok?(F(null),n==null||n(T.module,f)):f&&F({...T,conflict:f})},onOverwrite:async()=>{const f=await N.save(T.module,{force:!0});f!=null&&f.ok&&(F(null),n==null||n(T.module,f))},onReload:async()=>{await N.reload(T.module),F(null)}}),(T==null?void 0:T.kind)==="delete"&&e.jsx(c.NiceConfirmDialog,{visible:!0,variant:"warning",header:y("devStudio.delete.title","Delete module"),message:y("devStudio.delete.message","Delete {module} and all its files?").replace("{module}",te(T.module)),acceptLabel:y("devStudio.delete","Delete"),rejectLabel:y("devStudio.cancel","Cancel"),onReject:()=>F(null),onAccept:async()=>{const f=T.module;F(null),await N.deleteModule(f)&&X(z=>z.filter(D=>!("module"in D)||Y(D.module)!==Y(f)))}}),(T==null?void 0:T.kind)==="duplicate"&&e.jsx(Fe,{open:!0,title:y("devStudio.duplicate.title","Duplicate {module}").replace("{module}",te(T.module)),workspaces:Z,workspaceId:Z.some(f=>f.id===T.module.workspaceId)?T.module.workspaceId:void 0,idLabel:y("devStudio.duplicate.id","New module id"),initialId:`${T.module.id}Copy`,onClose:()=>F(null),onSubmit:async f=>{var ie;const z=T.module;F(null);const D=await N.duplicateModule(z,{workspaceId:f.workspaceId,id:f.id,packageId:(ie=ee(z))==null?void 0:ie.packageId});D&&x({workspaceId:D.workspaceId,id:D.id})}}),(T==null?void 0:T.kind)==="package"&&e.jsx(Fe,{open:!0,title:y("devStudio.package.new","New package"),workspaces:Z,workspaceId:T.workspaceId,idLabel:y("devStudio.package.id","Id"),withLabel:!0,onClose:()=>F(null),onSubmit:async f=>{F(null);const z=await N.savePackage({id:f.id,workspaceId:f.workspaceId,label:f.label});z&&I({key:`p:${z.workspaceId}/${z.id}`,kind:"package",pkg:z})}}),(T==null?void 0:T.kind)==="templates"&&N.templates&&e.jsx(vt,{open:!0,moduleId:T.module.id,templates:N.templates,onClose:()=>F(null),onApply:async f=>{F(null);for(const z of f)await N.saveTemplate(z,z.id)}})]})});exports.arrayFileKind=P.arrayFileKind;exports.buildDocuments=P.buildDocuments;exports.createMemoryStudioProvider=P.createMemoryStudioProvider;exports.defineManifestSection=P.defineManifestSection;exports.deriveDefaultRbac=P.deriveDefaultRbac;exports.detectJsonTextFormat=P.detectJsonTextFormat;exports.encodeDocument=P.encodeDocument;exports.endsWithAny=P.endsWithAny;exports.entitiesToSchemas=P.entitiesToSchemas;exports.fileName=P.fileName;exports.fitManifestSection=P.fitManifestSection;exports.i18nFileKind=P.i18nFileKind;exports.itemsFileKind=P.itemsFileKind;exports.jsonFallbackKind=P.jsonFallbackKind;exports.jsonFileKind=P.jsonFileKind;exports.jsonValueFitsSchema=P.jsonValueFitsSchema;exports.jsonValuesEqual=P.jsonValuesEqual;exports.keepTextFormat=P.keepTextFormat;exports.manifestSectionKeys=P.manifestSectionKeys;exports.modulePrefix=P.modulePrefix;exports.nativeDataSourcesKind=P.nativeDataSourcesKind;exports.nativeEntitiesKind=P.nativeEntitiesKind;exports.nativeFileKinds=P.nativeFileKinds;exports.nativeHooksKind=P.nativeHooksKind;exports.nativeI18nKind=P.nativeI18nKind;exports.nativeManifestKind=P.nativeManifestKind;exports.nativeRbacKind=P.nativeRbacKind;exports.nativeStudioPreset=P.nativeStudioPreset;exports.nativeViewsKind=P.nativeViewsKind;exports.nativeWorkflowsKind=P.nativeWorkflowsKind;exports.objectFileKind=P.objectFileKind;exports.parseJsonText=P.parseJsonText;exports.patchJsonText=P.patchJsonText;exports.patchJsonTextDetailed=P.patchJsonTextDetailed;exports.readTranslations=P.readTranslations;exports.resolveFileKind=P.resolveFileKind;exports.safeJson=P.safeJson;exports.slugifyModuleId=P.slugifyModuleId;exports.stringifyJsonText=P.stringifyJsonText;exports.textFallbackKind=P.textFallbackKind;exports.writeTranslations=P.writeTranslations;exports.NiceArrayField=Be;exports.NiceDevelopmentStudio=zt;exports.NiceEntityEditor=Te;exports.NiceI18nEditor=Ce;exports.NiceSchemaForm=pe;exports.aiFormConfigToFormFields=He;exports.aiFormFieldType=Ke;exports.formBuilderSchemaToNiceFormItems=We;exports.formFieldsToFormItems=_e;exports.formSchemaToJsonSchema=Ze;exports.jsonSchemaToFormItems=we;exports.schemaToFormItems=Je;exports.validateAgainstJsonSchema=Ie;exports.validateFormSchema=Ue;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),ge=require("@nice2dev/ui-core"),x=require("react"),h=require("@nice2dev/ui"),D=require("./studio.cjs");function Rt(t){var a,d;const i={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"},n=[];for(const s of t.sections)for(const o of s.fields)o.type==="heading"||o.type==="paragraph"||o.type==="divider"||o.type==="spacer"||o.type==="section"||n.push({field:o.name,label:o.label||o.name,type:i[o.type]||"text",placeholder:o.placeholder,hint:o.helpText,defaultValue:o.defaultValue,required:o.required||((a=o.validations)==null?void 0:a.some(u=>u.type==="required")),disabled:o.disabled,readOnly:o.readonly,group:s.title,options:(d=o.options)==null?void 0:d.map(u=>typeof u=="string"?{label:u,value:u}:{label:u.label,value:u.value})});return n}function rt(t){var n;const i={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:i[t.type]||"NiceTextInput",editorOptions:{placeholder:t.placeholder,disabled:t.disabled,readOnly:t.readonly,...t.props},colSpan:Math.ceil((t.colSpan||12)/6),validationRules:(n=t.validations)==null?void 0:n.map(a=>({type:a.type,message:a.message,...a.value!==void 0?{[a.type]:a.value}:{}})),helpText:t.helpText}}function At(t){const i=[];for(const n of t.sections)n.title?i.push({itemType:"group",caption:n.title,colCount:n.columns||2,items:n.fields.map(rt)}):i.push(...n.fields.map(rt));return i}function Lt(t){const i=[];t.version||i.push("Missing schema version"),t.id||i.push("Missing form ID"),(!t.sections||t.sections.length===0)&&i.push("Form must have at least one section");const n=new Set;for(const a of t.sections||[])for(const d of a.fields||[])d.id||i.push(`Field missing ID: ${d.name}`),d.name||i.push(`Field missing name: ${d.id}`),n.has(d.name)&&i.push(`Duplicate field name: ${d.name}`),n.add(d.name);return{valid:i.length===0,errors:i}}const qt={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",richtext:"richtext",markdown:"markdown"};function gt(t){return qt[String(t??"").toLowerCase()]??"text"}function Vt(t){return(Array.isArray(t)?t:t.fields).map((n,a)=>{const d=n.name??n.field??n.id??`field${a+1}`,s=n.validation??{},o=[],u=(c,l)=>{l!==void 0&&o.push({type:c,value:l,...s.message?{message:s.message}:{}})};return u("min",s.min),u("max",s.max),u("minLength",s.minLength),u("maxLength",s.maxLength),u("pattern",s.pattern),{id:n.id??d,name:d,type:gt(n.type),...n.label!==void 0?{label:n.label}:{},...n.placeholder!==void 0?{placeholder:n.placeholder}:{},...n.helpText!==void 0?{helpText:n.helpText}:{},...n.defaultValue!==void 0?{defaultValue:n.defaultValue}:{},...n.required?{required:!0}:{},...n.options?{options:[...n.options]}:{},...o.length?{validations:o}:{}}})}const Wt={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 Jt(t,i){if(i)for(const n of i)switch(n.type){case"minLength":typeof n.value=="number"&&(t.minLength=n.value);break;case"maxLength":typeof n.value=="number"&&(t.maxLength=n.value);break;case"min":typeof n.value=="number"&&(t.minimum=n.value);break;case"max":typeof n.value=="number"&&(t.maximum=n.value);break;case"pattern":typeof n.value=="string"&&(t.pattern=n.value);break;case"email":t.format="email";break;case"url":t.format="uri";break}}function Gt(t){if(t.type==="heading"||t.type==="paragraph"||t.type==="divider"||t.type==="spacer")return null;const i=Wt[t.type];if(!i)return null;const n={...i};return t.label&&(n.title=t.label),t.helpText&&(n.description=t.helpText),t.defaultValue!==void 0&&(n.default=t.defaultValue),t.options&&(t.type==="select"||t.type==="radio")&&(n.enum=t.options.map(a=>typeof a=="string"?a:a.value)),t.options&&t.type==="multiselect"&&(n.items={type:"string",enum:t.options.map(a=>typeof a=="string"?a:String(a.value))}),Jt(n,t.validations),n}function Ut(t){const i={},n=[],a=s=>{var o;for(const u of s){if(u.type==="section"&&u.children){a(u.children);continue}const c=Gt(u);c&&(i[u.name]=c,(u.required||(o=u.validations)!=null&&o.some(l=>l.type==="required"))&&n.push(u.name))}};for(const s of t.sections)a(s.fields);const d={$schema:"http://json-schema.org/draft-07/schema#",$id:t.id,type:"object",title:t.title,description:t.description,properties:i,additionalProperties:!1};return n.length>0&&(d.required=n),d}function lt(t){const{t:i}=ge.useNiceTranslation(),{value:n,onChange:a,readOnly:d}=t,[s,o]=x.useState(()=>{try{return n===void 0?"":JSON.stringify(n,null,2)}catch{return""}}),[u,c]=x.useState(null);return x.useEffect(()=>{try{o(n===void 0?"":JSON.stringify(n,null,2))}catch{}},[JSON.stringify(n)]),e.jsxs("div",{className:"nice-schema-form__json-field",children:[e.jsx("textarea",{className:"nice-schema-form__json-textarea",value:s,readOnly:d,spellCheck:!1,rows:Math.min(12,Math.max(3,s.split(`
|
|
2
|
+
`).length)),onChange:l=>{const r=l.target.value;o(r);const p=r.trim();if(p===""){c(null),a(void 0);return}try{a(JSON.parse(p)),c(null)}catch(m){c(m instanceof Error?m.message:i("jsonSchemaToFormItems.invalidJson","Invalid JSON"))}}}),u&&e.jsx("div",{className:"nice-schema-form__json-error",children:u})]})}function Ht(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 Yt(t,i,n,a={}){const d={field:t,label:i.title??t,required:n,hint:i.description,defaultValue:i.default};if(i.enum&&i.enum.length>0)return{...d,type:"select",options:i.enum.map(s=>({label:String(s),value:s}))};switch(i.type){case"number":case"integer":return{...d,type:"number"};case"boolean":return{...d,type:"checkbox"};case"string":return{...d,type:Ht(i.format)};case"array":{const s=i.items;if(s!=null&&s.enum&&s.enum.length>0)return{...d,type:"tags",options:s.enum.map(o=>({label:String(o),value:String(o)}))};if((s==null?void 0:s.type)==="object"&&s.properties&&a.renderArrayField){const o=a.renderArrayField;return{...d,render:(u,c)=>o(u??[],c,s,d.label)}}return(s==null?void 0:s.type)==="string"||(s==null?void 0:s.type)==="number"||(s==null?void 0:s.type)==="integer"?{...d,type:"tags"}:{...d,render:(o,u)=>e.jsx(lt,{value:o,onChange:u})}}case"object":if(a.renderObjectField){const s=a.renderObjectField;return{...d,render:(o,u)=>s(o??{},u,i,d.label)}}return{...d,render:(s,o)=>e.jsx(lt,{value:s,onChange:o})};default:return{...d,type:"text"}}}function We(t,i={}){const{uiSchema:n,renderArrayField:a,renderObjectField:d}=i,s={renderArrayField:a,renderObjectField:d},o=t.properties??{},u=new Set(t.required??[]);return Object.keys(o).map(c=>{const l=Yt(c,o[c],u.has(c),s);return n!=null&&n[c]?{...l,...n[c]}:l})}const Xt={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 Je(t,i={}){var d,s;const{uiSchema:n}=i,a=[];for(const o of t){if(o.type==="section"&&o.children){for(const l of Je(o.children,i))a.push(o.label?{...l,group:o.label}:l);continue}const u=Xt[o.type];if(!u)continue;const c={field:o.name,label:o.label,type:u,required:o.required||((d=o.validations)==null?void 0:d.some(l=>l.type==="required")),placeholder:o.placeholder,hint:o.helpText,defaultValue:o.defaultValue,disabled:o.disabled,readOnly:o.readonly,options:(s=o.options)==null?void 0:s.map(l=>typeof l=="string"?{label:l,value:l}:{label:l.label,value:l.value})};a.push(n!=null&&n[o.name]?{...c,...n[o.name]}:c)}return a}function ct(t){return t==null||t===""||Array.isArray(t)&&t.length===0}function Ge(t,i){const n=[],a=i.properties??{},d=new Set(i.required??[]);for(const s of Object.keys(a)){const o=a[s],u=t[s];if(d.has(s)&&ct(u)){n.push({field:s,message:`${o.title??s} is required`});continue}if(!ct(u)&&(o.enum&&!o.enum.includes(u)&&n.push({field:s,message:`${o.title??s} must be one of: ${o.enum.join(", ")}`}),(o.type==="number"||o.type==="integer")&&typeof u=="number"&&(o.minimum!==void 0&&u<o.minimum&&n.push({field:s,message:`${o.title??s} must be ≥ ${o.minimum}`}),o.maximum!==void 0&&u>o.maximum&&n.push({field:s,message:`${o.title??s} must be ≤ ${o.maximum}`})),o.type==="string"&&typeof u=="string"&&(o.minLength!==void 0&&u.length<o.minLength&&n.push({field:s,message:`${o.title??s} must be at least ${o.minLength} chars`}),o.maxLength!==void 0&&u.length>o.maxLength&&n.push({field:s,message:`${o.title??s} must be at most ${o.maxLength} chars`}),o.pattern)))try{new RegExp(o.pattern).test(u)||n.push({field:s,message:`${o.title??s} has an invalid format`})}catch{}}return n}const De="__nafRid";function Zt(t){return Array.isArray(t)?`[${t.length}]`:t&&typeof t=="object"?"{…}":t==null?"":String(t)}const Ue=x.forwardRef(function(i,n){const{value:a,defaultValue:d,onChange:s,itemSchema:o,title:u,readOnly:c=!1,columns:l,className:r,style:p,"data-testid":m}=i,[g,f]=h.useControllableState({value:a,defaultValue:d,fallbackValue:[],onChange:s,componentName:"NiceArrayField"}),v=o.properties??{},k=x.useMemo(()=>(l??Object.keys(v)).map(w=>{const _=v[w]??{},O={field:w,header:_.title??w};return _.type==="boolean"?(O.render=B=>B?e.jsx(h.NiceIcon,{name:"check",size:14,title:"true"}):"",O.align="center"):(_.type==="array"||_.type==="object")&&(O.render=B=>Zt(B)),O}),[o,l]),N=x.useMemo(()=>We(o),[o]),E=x.useMemo(()=>g.map((y,w)=>({...y,[De]:String(w)})),[g]),M=y=>{const{[De]:w,..._}=y;return _},S="nice-array-field"+(r?` ${r}`:"");return e.jsx("div",{ref:n,className:S,style:p,"data-testid":m,children:e.jsx(h.NiceDataGrid,{data:E,keyField:De,columns:k,editMode:"popup",formItems:N,editFormTitle:u?`${u} — item`:"Edit item",emptyText:`No items${u?` in ${u}`:""}`,compact:!0,onRowAdd:c?void 0:y=>f([...g,M(y)]),onRowEdit:c?void 0:(y,w)=>{const _=Number(y);f(g.map((O,B)=>B===_?M(w):O))},onRowDelete:c?void 0:y=>{const w=Number(y);f(g.filter((_,O)=>O!==w))}})})}),Qt=[{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 ei(t){const i=[],n=a=>{for(const d of a){if(d.type==="section"&&d.children){n(d.children);continue}d.required&&i.push({id:`${d.name}-required`,field:d.name,op:"required"});for(const s of d.validations??[])i.push({id:`${d.name}-${s.type}`,field:d.name,op:s.type,value:typeof s.value=="boolean"?void 0:s.value,message:s.message??(s.type==="required"?`${d.label??d.name} is required`:void 0)})}};return n(t),i}function ti(t,i){return h.evaluateValidation(ei(t),i).filter(n=>n.severity==="error").map(n=>({field:n.field,message:n.message}))}const we=x.forwardRef(function(i,n){const{schema:a,fields:d,uiSchema:s,value:o,defaultValue:u,onChange:c,onValidate:l,showJsonView:r=!1,columns:p=1,labelPosition:m="top",readOnly:g=!1,liveValidation:f=!0,validationRules:v,tutorial:k,className:N,style:E,id:M,"data-testid":S}=i,{t:y}=h.useNiceTranslation(),[w,_]=h.useControllableState({value:o,defaultValue:u,fallbackValue:{},onChange:c,componentName:"NiceSchemaForm"}),[O,B]=x.useState(!1),[P,ee]=x.useState(""),[Z,Y]=x.useState(null),J=x.useMemo(()=>a?We(a,{uiSchema:s,renderArrayField:(L,H,W,z)=>e.jsx(Ue,{value:L,onChange:H,itemSchema:W,title:z,readOnly:g})}):d?Je(d,{uiSchema:s}):[],[a,d,s,g]),C=x.useMemo(()=>{const L=a?Ge(w,a):d?ti(d,w):[];if(v!=null&&v.length){const H=h.evaluateValidation(v,w).filter(W=>W.severity==="error").map(W=>({field:W.field,message:W.message}));return[...L,...H]}return L},[a,d,w,v]);x.useEffect(()=>{l==null||l(C)},[C,l]),x.useEffect(()=>{if(O)try{ee(JSON.stringify(w,null,2)),Y(null)}catch{}},[O,w]);const $=(L,H)=>{_({...w,[L]:H})},R="nice-schema-form"+(N?` ${N}`:"");return e.jsxs("div",{ref:n,id:M,className:R,style:E,"data-testid":S,children:[k&&e.jsx("div",{className:"nice-schema-form__tutorial",children:e.jsx(h.NiceTutorialButton,{steps:h.resolveTutorial(k,Qt)})}),r&&e.jsxs("div",{className:"nice-schema-form__toolbar","data-tour":"sf-viewtoggle",children:[e.jsx("button",{type:"button",className:"nice-schema-form__tab"+(O?"":" nice-schema-form__tab--active"),onClick:()=>B(!1),children:y("schemaForm.tab.form","Form")}),e.jsx(h.NiceTooltip,{content:y("schemaForm.tab.json.help","Edit the raw JSON value directly"),children:e.jsx("button",{type:"button",className:"nice-schema-form__tab"+(O?" nice-schema-form__tab--active":""),onClick:()=>B(!0),children:y("schemaForm.tab.json","JSON")})})]}),O?e.jsxs("div",{className:"nice-schema-form__json",children:[e.jsx("textarea",{className:"nice-schema-form__json-textarea",value:P,readOnly:g,spellCheck:!1,rows:Math.min(24,Math.max(6,P.split(`
|
|
3
|
+
`).length)),onChange:L=>{const H=L.target.value;ee(H);try{const W=JSON.parse(H);Y(null),_(W)}catch(W){Y(W instanceof Error?W.message:y("schemaForm.invalidJson","Invalid JSON"))}}}),Z&&e.jsx("div",{className:"nice-schema-form__json-error",children:Z})]}):e.jsx(h.NiceForm,{items:J,data:w,onFieldChange:$,columns:p,labelPosition:m,readOnly:g}),f&&C.length>0&&e.jsx("ul",{className:"nice-schema-form__errors",role:"alert",children:C.map((L,H)=>e.jsx("li",{className:"nice-schema-form__error",children:L.message},`${L.field}-${H}`))})]})}),Pe="__eeFid",ii={},xt={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"]},kt={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 Re({title:t,help:i}){return e.jsxs("span",{className:"nice-entity-editor__field-label",children:[t,i?e.jsx(h.NiceTooltip,{content:i,children:e.jsx("span",{className:"nice-entity-editor__help",role:"img","aria-label":i,children:e.jsx(h.NiceIcon,{name:"info",size:14})})}):null]})}function ni({schema:t,value:i,onChange:n,readOnly:a}){const d=t.properties??{};return e.jsx("div",{className:"nice-entity-editor__field-form",children:Object.entries(d).map(([s,o])=>{const u=i[s],c=o.description,l=o.title??s;if(o.type==="boolean")return e.jsx("div",{className:"nice-entity-editor__field-row nice-entity-editor__field-row--check",children:e.jsx(h.NiceCheckbox,{label:e.jsx(Re,{title:l,help:c}),checked:!!u,onChange:p=>n(s,p),disabled:a})},s);if(Array.isArray(o.enum)&&o.enum.length>0)return e.jsxs("div",{className:"nice-entity-editor__field-row",children:[e.jsx(Re,{title:l,help:c}),e.jsx(h.NiceSelect,{options:o.enum.map(p=>({label:String(p),value:String(p)})),value:u==null?"":String(u),onChange:p=>n(s,p),clearable:!0,disabled:a})]},s);const r=o.type==="integer"||o.type==="number";return e.jsxs("div",{className:"nice-entity-editor__field-row",children:[e.jsx(Re,{title:l,help:c}),e.jsx(h.NiceTextInput,{value:u==null?"":String(u),onChange:p=>n(s,r?p===""?void 0:Number(p):p),disabled:a})]},s)})})}function si({fields:t,onChange:i,fieldSchema:n,readOnly:a}){const{t:d}=h.useNiceTranslation(),[s,o]=x.useState(null),u=x.useMemo(()=>t.map((p,m)=>({...p,[Pe]:String(m)})),[t]),c=x.useMemo(()=>[{field:"name",header:d("entityEditor.field.name","Name"),sortable:!0,render:p=>e.jsx("span",{className:"nice-entity-editor__name",children:String(p??"")})},{field:"dataType",header:d("entityEditor.field.type","Type"),sortable:!0,render:p=>e.jsx(h.NiceBadge,{variant:"secondary",size:"sm",outline:!0,children:String(p??"—")})},{field:"__flags",header:d("entityEditor.field.flags","Constraints"),headerTooltip:d("entityEditor.field.flags.help","Key / required / unique / indexed constraints on this field"),render:(p,m)=>{const g=[[!!(m!=null&&m.isPrimaryKey),"PK",d("entityEditor.flag.pk","Primary key"),"info"],[!!(m!=null&&m.isForeignKey),"FK",d("entityEditor.flag.fk","Foreign key"),"info"],[!!(m!=null&&m.isRequired),"Req",d("entityEditor.flag.required","Required (NOT NULL)"),"warning"],[!!(m!=null&&m.isUnique),"Uniq",d("entityEditor.flag.unique","Unique"),"secondary"],[!!(m!=null&&m.isIndexed),"Idx",d("entityEditor.flag.indexed","Indexed"),"secondary"]];return e.jsx("span",{className:"nice-entity-editor__flags",children:g.filter(([f])=>f).map(([,f,v,k])=>e.jsx(h.NiceTooltip,{content:v,children:e.jsx(h.NiceBadge,{variant:k,size:"sm",children:f})},f))})}}],[]),l=(p,m,g)=>{i(t.map((f,v)=>v===p?{...f,[m]:g}:f))},r=()=>{const p=[...t,{name:`field${t.length+1}`,dataType:"string"}];i(p),o(p.length-1)};if(s!=null&&t[s]){const p=t[s];return e.jsxs("div",{className:"nice-entity-editor__field-detail",children:[e.jsxs("header",{className:"nice-entity-editor__edit-header",children:[e.jsx(h.NiceTooltip,{content:d("entityEditor.field.backHint","Back to the field list"),children:e.jsx(h.NiceButton,{variant:"ghost",size:"sm",leftIcon:e.jsx(h.NiceIcon,{name:"arrow-left",size:14}),onClick:()=>o(null),children:d("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(p.name??d("entityEditor.field.untitled","New field"))})]}),e.jsx(ni,{schema:n,value:p,onChange:(m,g)=>l(s,m,g),readOnly:a}),e.jsx("div",{className:"nice-entity-editor__field-detail-actions",children:e.jsx(h.NiceButton,{variant:"primary",size:"sm",onClick:()=>o(null),children:d("entityEditor.field.done","Done")})})]})}return e.jsx(h.NiceDataGrid,{data:u,keyField:Pe,columns:c,searchable:!0,searchPlaceholder:d("entityEditor.field.search","Search fields…"),emptyText:d("entityEditor.field.empty","No fields yet. Add one to define this entity."),onRowClick:p=>o(Number(p[Pe])),onRowDelete:a?void 0:p=>i(t.filter((m,g)=>g!==Number(p))),toolbar:a?void 0:e.jsx(h.NiceButton,{variant:"primary",size:"sm",leftIcon:e.jsx(h.NiceIcon,{name:"plus",size:14}),onClick:r,children:d("entityEditor.field.add","Add field")}),compact:!0,striped:!0})}const He=x.forwardRef(function(i,n){const{value:a,defaultValue:d,onChange:s,entityMetaSchema:o=xt,fieldSchema:u=kt,fieldsKey:c="fields",validationsKey:l="validations",activeTab:r,defaultActiveTab:p="general",onActiveTabChange:m,extraTabs:g,readOnly:f=!1,className:v,style:k,id:N,"data-testid":E}=i,{t:M}=h.useNiceTranslation(),[S,y]=h.useControllableState({value:a,defaultValue:d,fallbackValue:ii,onChange:s,componentName:"NiceEntityForm"}),[w,_]=h.useControllableState({value:r,defaultValue:p,fallbackValue:"general",onChange:m,componentName:"NiceEntityForm"}),O=x.useMemo(()=>{const J=S[c];return Array.isArray(J)?J:[]},[S,c]),B=x.useMemo(()=>{const J=$=>{const R=$.toLowerCase();return/(int|long|decimal|double|float|number|money)/.test(R)?"number":/bool/.test(R)?"boolean":/date|time/.test(R)?"date":"string"},C=[];for(const $ of O){const R=String($.name??"");R&&C.push({field:R,label:String($.displayName??R),type:J(String($.dataType??"string"))})}return C},[O]),P=x.useMemo(()=>{const J=S[l];return Array.isArray(J)?J:[]},[S,l]),ee=J=>{y({...S,...J})},Z=[{id:"general",label:M("entityEditor.tab.general","General"),content:e.jsx(we,{schema:o,value:S,onChange:J=>ee(J),columns:2,readOnly:f,liveValidation:!0})},{id:"fields",label:M("entityEditor.tab.fields","Fields"),badge:O.length||void 0,content:e.jsx(si,{fields:O,onChange:J=>ee({[c]:J}),fieldSchema:u,readOnly:f})},{id:"validation",label:M("entityEditor.tab.validation","Validation"),badge:P.length||void 0,content:e.jsx(h.NiceValidationBuilder,{fields:B,value:P,onChange:J=>ee({[l]:J})})},...g??[]],Y="nice-entity-form"+(v?` ${v}`:"");return e.jsx("div",{ref:n,id:N,className:Y,style:k,"data-testid":E,children:e.jsx(h.NiceTabs,{tabs:Z,activeTab:w,onChange:_,variant:"enclosed"})})}),Ae="__eeRid",oi=[{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"}],bt=x.forwardRef(function(i,n){const{value:a,defaultValue:d,onChange:s,entityMetaSchema:o=xt,fieldSchema:u=kt,fieldsKey:c="fields",validationsKey:l="validations",nameKey:r="name",renderErPreview:p,readOnly:m=!1,tutorial:g,className:f,style:v,id:k,"data-testid":N}=i,{t:E}=h.useNiceTranslation(),[M,S]=h.useControllableState({value:a,defaultValue:d,fallbackValue:[],onChange:s,componentName:"NiceEntityEditor"}),[y,w]=x.useState("list"),[_,O]=x.useState(0),[B,P]=x.useState("general"),ee=Math.min(_,Math.max(0,M.length-1)),Z=M[ee],Y=y==="edit"&&Z!=null,J=x.useMemo(()=>M.map((z,G)=>({...z,[Ae]:String(G)})),[M]),C=z=>{O(z),P("general"),w("edit")},$=()=>{const z=[...M,{[r]:`Entity${M.length+1}`,[c]:[]}];S(z),O(z.length-1),P("general"),w("edit")},R=z=>{S(M.filter((G,re)=>re!==z)),O(G=>G>=z?Math.max(0,G-1):G)},L=x.useMemo(()=>[{field:r,header:E("entityEditor.col.name","Name"),sortable:!0,render:z=>e.jsx("span",{className:"nice-entity-editor__name",children:String(z??"")})},{field:"displayName",header:E("entityEditor.col.displayName","Display name"),sortable:!0,render:z=>e.jsx("span",{className:"nice-entity-editor__muted",children:String(z??"—")})},{field:"tableName",header:E("entityEditor.col.table","Table"),sortable:!0,render:z=>e.jsx("span",{className:"nice-entity-editor__muted",children:String(z??"—")})},{field:c,header:E("entityEditor.col.fields","Fields"),align:"center",headerTooltip:E("entityEditor.col.fields.help","Number of fields defined on this entity"),render:z=>e.jsx(h.NiceBadge,{variant:"secondary",size:"sm",children:Array.isArray(z)?z.length:0})},{field:"__flags",header:E("entityEditor.col.flags","Flags"),render:(z,G)=>e.jsxs("span",{className:"nice-entity-editor__flags",children:[G!=null&&G.isAudited?e.jsx(h.NiceTooltip,{content:E("entityEditor.flag.audited","Audited — tracks who changed each record and when"),children:e.jsx(h.NiceBadge,{variant:"info",size:"sm",outline:!0,children:E("entityEditor.flag.audited.abbr","Audit")})}):null,G!=null&&G.isSoftDeleteEnabled?e.jsx(h.NiceTooltip,{content:E("entityEditor.flag.softDelete","Soft delete — rows are flagged deleted, never physically removed"),children:e.jsx(h.NiceBadge,{variant:"secondary",size:"sm",outline:!0,children:E("entityEditor.flag.softDelete.abbr","Soft-del")})}):null]})}],[r,c]),H=p?[{id:"er",label:E("entityEditor.tab.er","ER diagram"),content:e.jsx("div",{className:"nice-entity-editor__er",children:p(M)})}]:void 0,W="nice-entity-editor"+(f?` ${f}`:"");return e.jsxs("div",{ref:n,id:k,className:W,style:v,"data-testid":N,children:[g&&e.jsx("div",{className:"nice-entity-editor__tutorial",children:e.jsx(h.NiceTutorialButton,{steps:h.resolveTutorial(g,oi)})}),Y?e.jsxs("div",{className:"nice-entity-editor__edit",children:[e.jsxs("header",{className:"nice-entity-editor__edit-header",children:[e.jsx(h.NiceTooltip,{content:E("entityEditor.backHint","Back to the entity list"),children:e.jsx(h.NiceButton,{variant:"ghost",size:"sm",leftIcon:e.jsx(h.NiceIcon,{name:"arrow-left",size:14}),onClick:()=>w("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((Z==null?void 0:Z[r])??E("entityEditor.untitled","Untitled entity"))}),!m&&e.jsx(h.NiceTooltip,{content:E("entityEditor.deleteHint","Delete this entity"),children:e.jsx(h.NiceButton,{variant:"ghost",size:"sm",leftIcon:e.jsx(h.NiceIcon,{name:"trash",size:14}),onClick:()=>{R(ee),w("list")},children:E("entityEditor.delete","Delete")})})]}),e.jsx(He,{value:Z,onChange:z=>S(M.map((G,re)=>re===ee?z:G)),entityMetaSchema:o,fieldSchema:u,fieldsKey:c,validationsKey:l,activeTab:B,onActiveTabChange:P,extraTabs:H,readOnly:m})]}):e.jsx("div",{className:"nice-entity-editor__list-view",children:e.jsx(h.NiceDataGrid,{data:J,keyField:Ae,columns:L,searchable:!0,searchPlaceholder:E("entityEditor.search","Search entities…"),emptyText:E("entityEditor.empty","No entities yet. Create one to get started."),onRowClick:z=>C(Number(z[Ae])),onRowDelete:m?void 0:z=>R(Number(z)),toolbar:m?void 0:e.jsx(h.NiceButton,{variant:"primary",size:"sm",leftIcon:e.jsx(h.NiceIcon,{name:"plus",size:14}),onClick:$,children:E("entityEditor.new","New entity")}),compact:!0,striped:!0})})]})}),ai=4e6;function di(t,i){const n=t.split(/\r?\n/),a=i.split(/\r?\n/);if(n.length*a.length>ai)return[...n.map(r=>({type:"remove",text:r})),...a.map(r=>({type:"add",text:r}))];const d=n.length,s=a.length,o=Array.from({length:d+1},()=>new Uint32Array(s+1));for(let r=d-1;r>=0;r--)for(let p=s-1;p>=0;p--)o[r][p]=n[r]===a[p]?o[r+1][p+1]+1:Math.max(o[r+1][p],o[r][p+1]);const u=[];let c=0,l=0;for(;c<d&&l<s;)n[c]===a[l]?(u.push({type:"same",text:n[c]}),c++,l++):o[c+1][l]>=o[c][l+1]?u.push({type:"remove",text:n[c++]}):u.push({type:"add",text:a[l++]});for(;c<d;)u.push({type:"remove",text:n[c++]});for(;l<s;)u.push({type:"add",text:a[l++]});return u}function jt({before:t,after:i,context:n=3}){const{t:a}=h.useNiceTranslation(),d=x.useMemo(()=>{const s=di(t,i),o=new Set;s.forEach((l,r)=>{if(l.type!=="same")for(let p=Math.max(0,r-n);p<=Math.min(s.length-1,r+n);p++)o.add(p)});const u=[];let c=0;return s.forEach((l,r)=>{o.has(r)?(c>0&&(u.push({type:"gap",count:c}),c=0),u.push(l)):c++}),c>0&&u.length>0&&u.push({type:"gap",count:c}),u},[t,i,n]);return d.length===0?e.jsx("p",{className:"nice-development-studio__muted",children:a("devStudio.diff.none","No changes.")}):e.jsx("pre",{className:"nice-development-studio__diff","aria-label":a("devStudio.diff.label","Changes"),children:d.map((s,o)=>s.type==="gap"?e.jsxs("span",{className:"nice-development-studio__diff-gap",children:[a("devStudio.diff.unchanged","{count} unchanged lines").replace("{count}",String(s.count)),`
|
|
4
|
+
`]},o):e.jsxs("span",{className:`nice-development-studio__diff-line nice-development-studio__diff-line--${s.type}`,children:[s.type==="add"?"+ ":s.type==="remove"?"- ":" ",s.text,`
|
|
5
|
+
`]},o))})}function ri({open:t,onClose:i,session:n,preset:a,locales:d,prefill:s,onCreated:o}){var M,S,y,w;const{t:u}=h.useNiceTranslation(),c=n.workspaces.filter(_=>!_.readOnly),l=a.requiredLocales??[],[r,p]=x.useState(()=>{var _;return{workspaceId:s.workspaceId&&c.some(O=>O.id===s.workspaceId)?s.workspaceId:((_=c[0])==null?void 0:_.id)??"",packageId:s.packageId,name:"",entities:[{name:"Item",fields:[{name:"Id",dataType:"Guid",isPrimaryKey:!0,isRequired:!0},{name:"Name",dataType:"string",isRequired:!0,maxLength:200}]}],locales:[...new Set([...l,...d.slice(0,2)])],views:!0,permissions:!0}}),[m,g]=x.useState(null),[f,v]=x.useState(!1),k=x.useMemo(()=>[...new Set((n.modulesByWs[r.workspaceId]??[]).map(_=>_.packageId).filter(Boolean))].sort(),[n.modulesByWs,r.workspaceId]);if(!t)return null;const N=new Set(Object.values(n.modulesByWs).flatMap(_=>_.map(O=>O.id))),E=async()=>{a.generateModule&&r.name.trim()&&g(await a.generateModule({...r,name:r.name.trim()},{existingIds:N}))};return e.jsx(h.NiceModal,{open:t,onClose:i,title:u("devStudio.wizard.title","New module"),size:"xl","data-testid":"studio-module-wizard",children:e.jsx(h.NiceWizard,{finishLabel:u("devStudio.wizard.create","Create module"),onCancel:i,onStepChange:_=>{_===3&&E()},onComplete:async()=>{if(f)return;v(!0);const _=await n.createModule({...r,name:r.name.trim()});v(!1),_&&(o({workspaceId:_.workspaceId,id:_.id}),i())},steps:[{id:"identity",title:u("devStudio.wizard.identity","Name and place"),validate:()=>r.name.trim()&&r.workspaceId?!0:u("devStudio.wizard.needName","Give the module a name."),content:e.jsxs("div",{className:"nice-development-studio__form",children:[e.jsx(h.NiceSelect,{label:u("devStudio.wizard.workspace","Project"),value:r.workspaceId,options:c.map(_=>({value:_.id,label:_.label})),onChange:_=>p({...r,workspaceId:String(_)})}),e.jsx(h.NiceTextInput,{label:u("devStudio.wizard.package","Package"),value:r.packageId??"",placeholder:k.join(", "),onChange:_=>p({...r,packageId:_||void 0})}),e.jsx(h.NiceTextInput,{label:u("devStudio.wizard.name","Name"),value:r.name,placeholder:u("devStudio.wizard.namePlaceholder","e.g. Bike rental"),onChange:_=>p({...r,name:_})}),e.jsx(h.NiceTextInput,{label:u("devStudio.wizard.description","Description"),value:r.description??"",onChange:_=>p({...r,description:_||void 0})})]})},{id:"entities",title:u("devStudio.wizard.entities","Entities"),content:e.jsx(bt,{value:r.entities,onChange:_=>p({...r,entities:_}),entityMetaSchema:(M=a.entities)==null?void 0:M.entityMetaSchema,fieldSchema:(S=a.entities)==null?void 0:S.fieldSchema,fieldsKey:(y=a.entities)==null?void 0:y.fieldsKey,nameKey:(w=a.entities)==null?void 0:w.nameKey})},{id:"options",title:u("devStudio.wizard.options","Options"),content:e.jsxs("div",{className:"nice-development-studio__form",children:[e.jsxs("fieldset",{className:"nice-development-studio__fieldset",children:[e.jsx("legend",{children:u("devStudio.wizard.locales","Languages")}),[...new Set([...l,...d])].map(_=>e.jsx(h.NiceCheckbox,{label:_,checked:r.locales.includes(_),disabled:l.includes(_),onChange:O=>p({...r,locales:O?[...r.locales,_]:r.locales.filter(B=>B!==_)})},_))]}),e.jsx(h.NiceCheckbox,{label:u("devStudio.wizard.views","A list and a form view per entity"),checked:!!r.views,onChange:_=>p({...r,views:_})}),e.jsx(h.NiceCheckbox,{label:u("devStudio.wizard.permissions","Viewer, editor and admin permissions"),checked:!!r.permissions,onChange:_=>p({...r,permissions:_})})]})},{id:"review",title:u("devStudio.wizard.review","Review"),content:m?e.jsxs("div",{children:[e.jsx("p",{children:u("devStudio.wizard.willCreate","Module {id} with these files:").replace("{id}",m.id)}),e.jsx("ul",{className:"nice-development-studio__list",children:m.files.map(_=>e.jsxs("li",{children:[e.jsx(h.NiceIcon,{name:"file",size:12})," ",_.path]},_.path))})]}):e.jsx("p",{className:"nice-development-studio__muted",children:u("devStudio.wizard.generating","Generating…")})}]})})}function li({open:t,moduleLabel:i,changes:n,original:a,conflict:d,onSave:s,onOverwrite:o,onReload:u,onClose:c}){const{t:l}=h.useNiceTranslation();return t?e.jsxs(h.NiceModal,{open:t,onClose:c,size:"xl",title:l("devStudio.review.title","Save {module}").replace("{module}",i),"data-testid":"studio-review",footer:d?e.jsxs(e.Fragment,{children:[e.jsx(h.NiceButton,{variant:"ghost",onClick:c,children:l("devStudio.cancel","Cancel")}),e.jsx(h.NiceButton,{variant:"secondary",onClick:u,children:l("devStudio.review.reload","Reload theirs (drop mine)")}),e.jsx(h.NiceButton,{variant:"danger",onClick:o,children:l("devStudio.review.overwrite","Overwrite with mine")})]}):e.jsxs(e.Fragment,{children:[e.jsx(h.NiceButton,{variant:"ghost",onClick:c,children:l("devStudio.cancel","Cancel")}),e.jsx(h.NiceButton,{variant:"primary",onClick:s,children:l("devStudio.review.save","Save {count} files").replace("{count}",String(n.length))})]}),children:[d&&e.jsxs("p",{className:"nice-development-studio__error",role:"alert",children:[l("devStudio.review.conflict","These files changed since you opened them:")," ",d.conflicts.map(r=>r.path).join(", ")]}),n.map(r=>e.jsxs("section",{className:"nice-development-studio__source",children:[e.jsx("h4",{className:"nice-development-studio__source-title",children:r.type==="delete"?l("devStudio.change.delete","Delete {path}").replace("{path}",r.path):r.baseVersion===void 0&&!a(r.path)?l("devStudio.change.new","New file {path}").replace("{path}",r.path):r.path}),e.jsx(jt,{before:a(r.path),after:r.type==="write"?r.text:""})]},r.path))]}):null}function ci({open:t,moduleId:i,templates:n,onApply:a,onClose:d}){const{t:s}=h.useNiceTranslation(),o=x.useMemo(()=>n.filter(p=>p.modules.some(m=>m.moduleId===i)).map(p=>p.id),[n,i]),[u,c]=x.useState(o);if(!t)return null;const l=n.map(p=>{var m,g;return{id:p.id,label:((m=p.translations.en)==null?void 0:m.name)??((g=Object.values(p.translations)[0])==null?void 0:g.name)??p.id}}),r=[{field:"label",header:s("devStudio.explorer.name","Name")}];return e.jsx(h.NiceModal,{open:t,onClose:d,title:s("devStudio.picker.title","Templates with {module}").replace("{module}",i),"data-testid":"studio-template-picker",footer:e.jsxs(e.Fragment,{children:[e.jsx(h.NiceButton,{variant:"ghost",onClick:d,children:s("devStudio.cancel","Cancel")}),e.jsx(h.NiceButton,{variant:"primary",onClick:()=>{const p=n.filter(m=>u.includes(m.id)!==o.includes(m.id)).map(m=>({...m,modules:u.includes(m.id)?[...m.modules,{moduleId:i}]:m.modules.filter(g=>g.moduleId!==i)}));a(p)},children:s("devStudio.apply","Apply")})]}),children:e.jsx(h.NiceTreeGrid,{data:l,columns:r,keyField:"id",sortable:!1,compact:!0,checkable:!0,checkedKeys:u,onCheckedChange:c,searchable:!0,"aria-label":s("devStudio.explorer.templates","Templates")})})}function ut({open:t,title:i,workspaces:n,workspaceId:a,idLabel:d,initialId:s="",withLabel:o,onSubmit:u,onClose:c}){var k;const{t:l}=h.useNiceTranslation(),[r,p]=x.useState(a??((k=n[0])==null?void 0:k.id)??""),[m,g]=x.useState(s),[f,v]=x.useState("");return t?e.jsx(h.NiceModal,{open:t,onClose:c,title:i,footer:e.jsxs(e.Fragment,{children:[e.jsx(h.NiceButton,{variant:"ghost",onClick:c,children:l("devStudio.cancel","Cancel")}),e.jsx(h.NiceButton,{variant:"primary",disabled:!m.trim()||!r,onClick:()=>u({workspaceId:r,id:m.trim(),label:f.trim()||m.trim()}),children:l("devStudio.ok","OK")})]}),children:e.jsxs("div",{className:"nice-development-studio__form",children:[e.jsx(h.NiceSelect,{label:l("devStudio.wizard.workspace","Project"),value:r,options:n.map(N=>({value:N.id,label:N.label})),onChange:N=>p(String(N))}),e.jsx(h.NiceTextInput,{label:d,value:m,onChange:g}),o&&e.jsx(h.NiceTextInput,{label:l("devStudio.package.label","Name"),value:f,onChange:v})]})}):null}const mt=t=>JSON.stringify(t??null,null,2);function Ye({value:t,onChange:i,readOnly:n,height:a=320,label:d}){const{t:s}=h.useNiceTranslation(),[o,u]=x.useState(()=>mt(t)),[c,l]=x.useState(null),r=x.useRef(t);return x.useEffect(()=>{r.current!==t&&(r.current=t,u(mt(t)),l(null))},[t]),e.jsxs("div",{className:"nice-development-studio__json",role:"group","aria-label":d,children:[e.jsx(h.NiceSimpleCodeEditor,{value:o,language:"json",height:a,readOnly:n,lineNumbers:!0,onChange:p=>{u(p);try{const m=JSON.parse(p);l(null),r.current=m,i==null||i(m)}catch(m){l(m instanceof Error?m.message:String(m))}}}),c&&e.jsxs("p",{className:"nice-development-studio__error",role:"alert",children:[s("devStudio.json.invalid","Not valid JSON:")," ",c]})]})}const ui=[{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"}],Xe=x.forwardRef(function(i,n){const{value:a,defaultValue:d,onChange:s,locales:o,allowEditLocales:u=!0,allowEditKeys:c=!0,highlightMissing:l=!0,readOnly:r=!1,tutorial:p,className:m,style:g,id:f,"data-testid":v}=i,{t:k}=ge.useNiceTranslation(),[N,E]=ge.useControllableState({value:a,defaultValue:d,fallbackValue:{},onChange:s,componentName:"NiceI18nEditor"}),[M,S]=x.useState(""),[y,w]=x.useState(""),_=x.useMemo(()=>o??Object.keys(N),[o,N]),O=x.useMemo(()=>{const $=new Set;for(const R of Object.keys(N))for(const L of Object.keys(N[R]??{}))$.add(L);return[...$].sort()},[N]),B=($,R,L)=>{E({...N,[$]:{...N[$]??{},[R]:L}})},P=($,R)=>{if(!R||R===$)return;const L={};for(const H of Object.keys(N)){const W={...N[H]??{}};$ in W&&(W[R]=W[$],delete W[$]),L[H]=W}E(L)},ee=$=>{const R={};for(const L of Object.keys(N)){const H={...N[L]??{}};delete H[$],R[L]=H}E(R)},Z=()=>{const $=M.trim();if(!$||O.includes($))return;const R={};for(const L of _)R[L]={...N[L]??{},[$]:""};for(const L of Object.keys(N))R[L]||(R[L]=N[L]);E(R),S("")},Y=()=>{const $=y.trim();if(!$||N[$])return;const R={};for(const L of O)R[L]="";E({...N,[$]:R}),w("")},J=$=>{const R={...N};delete R[$],E(R)},C="nice-i18n-editor"+(m?` ${m}`:"");return e.jsxs("div",{ref:n,id:f,className:C,style:g,"data-testid":v,children:[p&&e.jsx("div",{className:"nice-i18n-editor__tutorial",children:e.jsx(ge.NiceTutorialButton,{steps:ge.resolveTutorial(p,ui)})}),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:k("i18nEditor.keyHead","Key")}),_.map($=>e.jsxs("th",{className:"nice-i18n-editor__locale-head",children:[e.jsx("span",{children:$}),u&&!r&&e.jsx("button",{type:"button",className:"nice-i18n-editor__locale-remove","aria-label":`${k("i18nEditor.removeLocale","Remove locale")} ${$}`,onClick:()=>J($),children:e.jsx(ge.NiceIcon,{name:"close",size:12})})]},$))]})}),e.jsxs("tbody",{children:[O.map($=>e.jsxs("tr",{children:[e.jsxs("td",{className:"nice-i18n-editor__key-cell",children:[c&&!r?e.jsx("input",{className:"nice-i18n-editor__key-input",defaultValue:$,onBlur:R=>P($,R.target.value.trim()),"aria-label":k("i18nEditor.keyAria","Translation key")}):e.jsx("span",{className:"nice-i18n-editor__key-text",children:$}),c&&!r&&e.jsx("button",{type:"button",className:"nice-i18n-editor__key-remove","aria-label":`${k("i18nEditor.removeKey","Remove key")} ${$}`,onClick:()=>ee($),children:e.jsx(ge.NiceIcon,{name:"close",size:12})})]}),_.map(R=>{var W;const L=((W=N[R])==null?void 0:W[$])??"",H=l&&L==="";return e.jsx("td",{className:"nice-i18n-editor__cell",children:e.jsx("input",{className:"nice-i18n-editor__cell-input"+(H?" nice-i18n-editor__cell-input--missing":""),value:L,readOnly:r,onChange:z=>B(R,$,z.target.value),"aria-label":`${$} (${R})`})},R)})]},$)),O.length===0&&e.jsx("tr",{children:e.jsx("td",{className:"nice-i18n-editor__empty",colSpan:_.length+1,children:k("i18nEditor.empty","No translation keys yet.")})})]})]})}),!r&&(c||u)&&e.jsxs("div",{className:"nice-i18n-editor__toolbar","data-tour":"i18n-add",children:[c&&e.jsxs("div",{className:"nice-i18n-editor__add",children:[e.jsx("input",{className:"nice-i18n-editor__add-input",placeholder:k("i18nEditor.newKeyPlaceholder","new.key"),value:M,onChange:$=>S($.target.value),onKeyDown:$=>{$.key==="Enter"&&Z()},"aria-label":k("i18nEditor.newKeyAria","New key")}),e.jsxs("button",{type:"button",onClick:Z,children:["+ ",k("i18nEditor.addKey","Key")]})]}),u&&e.jsxs("div",{className:"nice-i18n-editor__add",children:[e.jsx("input",{className:"nice-i18n-editor__add-input",placeholder:k("i18nEditor.newLocalePlaceholder","locale (e.g. de)"),value:y,onChange:$=>w($.target.value),onKeyDown:$=>{$.key==="Enter"&&Y()},"aria-label":k("i18nEditor.newLocaleAria","New locale")}),e.jsxs("button",{type:"button",onClick:Y,children:["+ ",k("i18nEditor.addLocale","Locale")]})]})]})]})}),X=t=>`${t.workspaceId}/${t.id}`;function Le(t,i,n){const a=new Set(t.deleted),d=new Map;for(const m of t.files)a.has(m.path)||d.set(m.path,t.raw[m.path]!==void 0?{...m,text:t.raw[m.path]}:m);for(const[m,g]of Object.entries(t.raw))!d.has(m)&&!a.has(m)&&d.set(m,{path:m,text:g});const s=[...d.values()],o={moduleId:t.key.id,files:s,locales:n},u=D.buildDocuments(i.kinds,s,o),c=new Map(s.map(m=>[m.path,m.text])),l={};for(const m of u)if(m.key in t.drafts)try{const g=m.kind.encode(t.drafts[m.key],s.filter(f=>m.paths.includes(f.path)),o);for(const f of g.files)c.set(f.path,f.text),a.delete(f.path);for(const f of g.deleted??[])c.delete(f),a.add(f)}catch(g){l[m.key]=g instanceof Error?g.message:String(g)}const r=new Map(t.files.map(m=>[m.path,m])),p=[];for(const[m,g]of c){const f=r.get(m);(!f||f.text!==g)&&p.push({type:"write",path:m,text:g,baseVersion:f==null?void 0:f.version})}for(const m of a){const g=r.get(m);g&&p.push({type:"delete",path:m,baseVersion:g.version})}return{...t,working:s,documents:u,changes:p,pending:c,encodeErrors:l,dirty:p.length>0}}function St(t,i){const n=[];for(const a of t.documents){if(a.error&&n.push({severity:"error",code:"file.unreadable",message:`${a.paths[0]} cannot be read: ${a.error}`,messageKey:"devStudio.issue.unreadable",params:{path:a.paths[0]},moduleId:t.key.id,path:a.paths[0]}),a.kind.editor!=="manifest"||!i.manifestSections)continue;const d=t.drafts[a.key]??a.model??{};for(const s of i.manifestSections){const{section:o}=D.fitManifestSection(s,d);if(o.schema)for(const u of Ge(d,o.schema))n.push({severity:"error",code:"manifest.schema",message:`${o.title}: ${u.field} — ${u.message}`,moduleId:t.key.id,path:a.paths[0],pointer:`/${u.field.replace(/\./g,"/")}`})}}for(const[a,d]of Object.entries(t.encodeErrors))n.push({severity:"error",code:"document.encode",message:`${a}: ${d}`,moduleId:t.key.id});if(i.validateModule){const a=[...t.pending.entries()].map(([d,s])=>({path:d,text:s}));n.push(...i.validateModule({key:t.key,files:a,documents:t.documents}).map(d=>({...d,moduleId:d.moduleId??t.key.id})))}return n}const mi=t=>t instanceof Error?t.message:String(t);function pi(t,i,n){const[a,d]=x.useState([]),[s,o]=x.useState({}),[u,c]=x.useState({}),[l,r]=x.useState(null),[p,m]=x.useState({}),[g,f]=x.useState({}),[v,k]=x.useState(0),[N,E]=x.useState([]),M=x.useRef({provider:t,preset:i,options:n});M.current={provider:t,preset:i,options:n};const S=x.useCallback((T,j,I)=>{E(F=>[...F,{level:T,message:j,data:I,timestamp:Date.now()}].slice(-300))},[]),y=x.useCallback(async(T,j)=>{var I,F;k(A=>A+1);try{return await j()}catch(A){S("error",`${T}: ${mi(A)}`),(F=(I=M.current.options).onError)==null||F.call(I,A,T);return}finally{k(A=>A-1)}},[S]),w=x.useCallback(async()=>{const T=M.current.provider;T&&await y("List",async()=>{const j=await T.listWorkspaces();d(j);const I=await Promise.all(j.map(async F=>{const[A,V]=await Promise.all([T.listModules(F.id),T.listPackages?T.listPackages(F.id):Promise.resolve(void 0)]);return[F.id,A,V]}));o(Object.fromEntries(I.map(([F,A])=>[F,A]))),c(Object.fromEntries(I.filter(([,,F])=>F).map(([F,,A])=>[F,A]))),r(T.listTemplates?await T.listTemplates():null)})},[y]);x.useEffect(()=>{w()},[t,w]);const _=x.useMemo(()=>{const T={};for(const[j,I]of Object.entries(p))T[j]=Le(I,i,n.locales);return T},[p,i,n.locales]),O=x.useCallback(async T=>{const j=X(T),I=M.current.provider;if(!I)return;const F=await y(`Open ${T.id}`,()=>I.readModule(T));if(!F)return;const A={key:T,files:F,raw:{},deleted:[],drafts:{}};return m(V=>V[j]?V:{...V,[j]:A}),S("info",`Opened ${T.id} (${F.length} files)`),Le(A,M.current.preset,M.current.options.locales)},[y,S]),B=x.useCallback((T,j)=>{const I=X(T);m(F=>F[I]?{...F,[I]:j(F[I])}:F)},[]),P=x.useCallback((T,j,I)=>B(T,F=>({...F,drafts:{...F.drafts,[j]:I}})),[B]),ee=x.useCallback((T,j,I,F=[])=>B(T,A=>{const V={...A.raw};I===null?delete V[j]:V[j]=I;const Q={...A.drafts};for(const U of F)delete Q[U];return{...A,raw:V,drafts:Q,deleted:A.deleted.filter(U=>U!==j)}}),[B]),Z=x.useCallback((T,j)=>B(T,I=>{const F={...I.raw};delete F[j];const A=!I.files.some(V=>V.path===j);return{...I,raw:F,deleted:A?I.deleted:[...new Set([...I.deleted,j])]}}),[B]),Y=x.useCallback(T=>B(T,j=>({...j,raw:{},deleted:[],drafts:{}})),[B]),J=x.useCallback(async T=>{const j=M.current.provider;if(!j)return;const I=await y(`Reload ${T.id}`,()=>j.readModule(T));I&&(B(T,()=>({key:T,files:I,raw:{},deleted:[],drafts:{}})),S("info",`Reloaded ${T.id}`))},[y,B,S]),C=x.useCallback(T=>{const j=X(T);m(I=>{const F={...I};return delete F[j],F})},[]),$=x.useCallback(async(T,j={})=>{var te;const I=M.current.provider,F=X(T),A=p[F];if(!I||!A)return;const V=Le(A,M.current.preset,M.current.options.locales);if(V.changes.length===0)return{ok:!0};const Q=j.force?V.changes.map(ae=>({...ae,baseVersion:void 0})):V.changes,U=await y(`Save ${T.id}`,()=>I.writeModule(T,Q));if(!U)return;if(!U.ok)return S("warn",`${T.id}: ${U.conflicts.length} file(s) changed meanwhile`),U;const le=[];for(const[ae,ce]of V.pending){const de=A.files.find(Ne=>Ne.path===ae);le.push({...de,path:ae,text:ce,version:((te=U.versions)==null?void 0:te[ae])??(de==null?void 0:de.version)})}return B(T,()=>({key:T,files:le,raw:{},deleted:[],drafts:{}})),S("info",`Saved ${T.id}: ${Q.map(ae=>`${ae.type} ${ae.path}`).join(", ")}`),U},[p,y,B,S]),R=x.useCallback(async T=>{const j=X(T),I=_[j];if(!I)return[];const F=St(I,i),A=M.current.provider;let V=[];if(A!=null&&A.validate){const U=[...I.pending.entries()].map(([le,te])=>({path:le,text:te}));V=await y(`Validate ${T.id}`,()=>A.validate(T,U))??[]}f(U=>({...U,[j]:V}));const Q=[...F,...V];S(Q.some(U=>U.severity==="error")?"warn":"info",Q.length===0?`${T.id}: no problems`:`${T.id}: ${Q.length} problem(s)`);for(const U of Q)S(U.severity==="error"?"error":U.severity==="warning"?"warn":"info",`${U.path?`${U.path}: `:""}${U.message}`);return Q},[_,i,y,S]),L=x.useCallback(async T=>{const{provider:j,preset:I}=M.current;if(!(j!=null&&j.createModule)||!I.generateModule)return;const F=new Set(Object.values(s).flatMap(Q=>Q.map(U=>U.id))),A=await y("Generate module",()=>I.generateModule(T,{existingIds:F}));if(!A)return;const V=await y(`Create ${A.id}`,()=>j.createModule({workspaceId:T.workspaceId,packageId:A.packageId??T.packageId,id:A.id,files:A.files}));return V&&(S("info",`Created ${V.id}`),await w()),V},[s,y,S,w]),H=x.useCallback(async(T,j)=>{const{provider:I,preset:F}=M.current;if(!(I!=null&&I.createModule)||!F.duplicateModule)return;const A=await y(`Read ${T.id}`,()=>I.readModule(T));if(!A)return;const V=await y("Duplicate",()=>F.duplicateModule(A,j));if(!V)return;const Q=await y(`Create ${V.id}`,()=>I.createModule({workspaceId:j.workspaceId,packageId:V.packageId??j.packageId,id:V.id,files:V.files}));return Q&&(S("info",`Duplicated ${T.id} as ${Q.id}`),await w()),Q},[y,S,w]),W=x.useCallback(async T=>{const j=M.current.provider;if(!(j!=null&&j.deleteModule))return!1;const I=await y(`Delete ${T.id}`,async()=>(await j.deleteModule(T),!0));return I&&(C(T),S("info",`Deleted ${T.id}`),await w()),!!I},[y,C,S,w]),z=x.useCallback(async T=>{const j=M.current.provider;if(!(j!=null&&j.savePackage))return;const I=await y(`Save package ${T.id}`,()=>j.savePackage(T));return I&&(S("info",`Saved package ${I.id}`),await w()),I},[y,S,w]),G=x.useCallback(async(T,j)=>{const I=M.current.provider;if(!(I!=null&&I.saveTemplate))return;const F=await y(`Save template ${T.id}`,()=>I.saveTemplate(T,j?{previousId:j}:void 0));return F&&I.listTemplates&&(r(await I.listTemplates()),S("info",`Saved template ${F.id}`)),F},[y,S]),re=x.useCallback(async T=>{const j=M.current.provider;if(!(j!=null&&j.deleteTemplate))return!1;const I=await y(`Delete template ${T}`,async()=>(await j.deleteTemplate(T),!0));return I&&j.listTemplates&&(r(await j.listTemplates()),S("info",`Deleted template ${T}`)),!!I},[y,S]);return{workspaces:a,modulesByWs:s,packagesByWs:u,templates:l,modules:_,serverIssues:g,busy:v>0,logs:N,clearLogs:()=>E([]),log:S,refresh:w,openModule:O,close:C,setDraft:P,setRaw:ee,deleteFile:Z,discard:Y,reload:J,save:$,validate:R,createModule:L,duplicateModule:H,deleteModule:W,savePackage:z,saveTemplate:G,deleteTemplate:re}}const xe="__none",Me="t:",hi={entities:"entities",views:"views",workflows:"workflows",i18n:"translations",permissions:"permissions",rbac:"access",dataSources:"dataSources",seeds:"seeds",hooks:"hooks",script:"scripts"},fi=["entities","views","workflows","translations","permissions","access","dataSources","seeds","hooks","scripts"],ye={entities:"database",views:"grid",workflows:"git-branch",translations:"globe",permissions:"shield",access:"users",dataSources:"server",seeds:"list",hooks:"zap",scripts:"code",files:"folder"},vi={views:"grid",workflows:"git-branch",dataSources:"server"},wt=t=>hi[t.kind.editor];function be(t,i,n){const a=(d,s)=>t(d,s).replace("{count}",String(n??0));switch(i){case"entities":return a("devStudio.group.entities","Entities: {count}");case"views":return a("devStudio.group.views","Views: {count}");case"workflows":return a("devStudio.group.workflows","Workflows: {count}");case"dataSources":return a("devStudio.group.dataSources","Data sources: {count}");case"scripts":return a("devStudio.group.scripts","Scripts: {count}");case"files":return a("devStudio.group.files","Files: {count}");case"translations":return t("devStudio.group.translations","Translations");case"permissions":return t("devStudio.group.permissions","Permissions");case"access":return t("devStudio.group.access","Access");case"seeds":return t("devStudio.group.seeds","Seed data");case"hooks":return t("devStudio.group.hooks","Lifecycle hooks")}}function Nt(t){switch(t.kind){case"workspace":return`w|${t.workspaceId}`;case"package":return`p|${t.workspaceId}|${t.packageId??xe}`;case"module":return`m|${X(t.module)}`;case"group":return`g|${X(t.module)}|${t.group}`;case"entity":return`e|${X(t.module)}|${t.docKey}|${t.index}`;case"item":return`i|${X(t.module)}|${t.group}|${t.docKey}|${t.itemKey}`;case"document":return`d|${X(t.module)}|${t.docKey}`;case"panel":return`x|${X(t.module)}|${t.panelKey}`;case"file":return`f|${X(t.module)}|${t.path}`;case"templates":return"t";case"category":return`c|${t.category}`;case"template":return`t|${t.templateId}`;case"templateModule":return`tm|${t.templateId}|${t.moduleId}`}}const ne=(t,i)=>t.drafts[i.key]??i.model,me=(t,i)=>t.documents.find(n=>n.key===i),je=(t,i)=>t.changes.some(n=>i.paths.includes(n.path));function Ze(t){const i=[];for(const n of t.documents){if(n.kind.editor!=="entities")continue;const a=ne(t,n);Array.isArray(a)&&a.forEach((d,s)=>i.push({docKey:n.key,index:s,entity:d}))}return i}const Ve=t=>Ze(t).map(i=>i.entity),Qe=(t,i="name")=>String(t.displayName||t[i]||"");function pe(t,i){const n=ne(t,i);return Array.isArray(n)?i.kind.editor==="dataSources"?n.map(a=>{const d=a;return{key:String(d.key??""),label:d.label||String(d.key??""),definition:a,source:a}}):n:[]}function et(t,i,n){return n===null?t.filter((a,d)=>d!==i):t.map((a,d)=>d===i?n:a)}function _t(t,i,n){return n===null?t.filter(a=>a.key!==i):t.map(a=>a.key===i?n:a)}function It(t,i,n){const a=new Map((i??[]).map(d=>[d.id,d]));for(const d of n){const s=d.packageId??xe;a.has(s)||a.set(s,{id:s,workspaceId:t,label:d.packageId??"",derived:!0})}return[...a.values()].sort((d,s)=>d.id===xe?1:s.id===xe?-1:d.label.localeCompare(s.label))}const Ee=(t,i)=>t&&/^[a-z0-9-]+$/.test(t)?t:i,pt=t=>t.slice(t.lastIndexOf("/")+1);function yi(t,i,n){var c;const{t:a}=n,d=i.key,s=new Map;for(const l of i.documents){const r=wt(l);r&&s.set(r,[...s.get(r)??[],l])}const o=(l,r)=>({id:`${r}/d:${l.key}`,node:{kind:"document",module:d,docKey:l.key},label:pt(l.paths[0]??l.label),icon:"warning",noForm:!0,dirty:je(i,l)}),u=[];for(const l of fi){const r=s.get(l);if(!r)continue;const p=`${t}/g:${l}`,m={kind:"group",module:d,group:l};if(l==="entities"){const g=[];for(const v of r){const k=ne(i,v);if(!Array.isArray(k)){g.push(o(v,p));continue}const N=je(i,v);k.forEach((E,M)=>{const S=E.fields;g.push({id:`${p}/e:${v.key}#${M}`,node:{kind:"entity",module:d,docKey:v.key,index:M},label:Qe(E)||`#${M+1}`,icon:"table",info:Array.isArray(S)?String(S.length):void 0,dirty:N,search:String(E.name??"")})})}const f=g.filter(v=>v.node.kind==="entity").length;u.push({id:p,node:m,label:be(a,l,f),icon:ye[l],children:g});continue}if(l==="views"||l==="workflows"||l==="dataSources"){const g=[];for(const v of r){if(v.model===void 0){g.push(o(v,p));continue}const k=je(i,v);for(const N of pe(i,v))g.push({id:`${p}/i:${v.key}#${N.key}`,node:{kind:"item",module:d,group:l,docKey:v.key,itemKey:N.key},label:N.label||N.key,icon:vi[l],noForm:N.definition===void 0,dirty:k,search:N.key})}const f=g.filter(v=>v.node.kind==="item").length;u.push({id:p,node:m,label:be(a,l,f),icon:ye[l],children:g});continue}if(l==="scripts"){u.push({id:p,node:m,label:be(a,l,r.length),icon:ye[l],children:r.map(g=>({id:`${p}/d:${g.key}`,node:{kind:"document",module:d,docKey:g.key},label:pt(g.paths[0]??g.label),icon:"code",dirty:je(i,g),search:g.paths.join(" ")}))});continue}if(r.length===1){const g=r[0];u.push({id:p,node:{kind:"document",module:d,docKey:g.key},label:be(a,l),icon:ye[l],noForm:g.model===void 0,dirty:je(i,g)});continue}u.push({id:p,node:m,label:be(a,l),icon:ye[l],children:r.map(g=>({id:`${p}/d:${g.key}`,node:{kind:"document",module:d,docKey:g.key},label:g.label,icon:ye[l],noForm:g.model===void 0,dirty:je(i,g),search:g.paths.join(" ")}))})}for(const l of((c=n.panels)==null?void 0:c.call(n,i))??[])u.push({id:`${t}/x:${l.key}`,node:{kind:"panel",module:d,panelKey:l.key},label:l.label,icon:"puzzle"});if(n.advanced){const l=new Set(i.changes.map(p=>p.path)),r=[...i.working].sort((p,m)=>p.path.localeCompare(m.path));u.push({id:`${t}/g:files`,node:{kind:"group",module:d,group:"files"},label:be(a,"files",r.length),icon:ye.files,children:r.map(p=>({id:`${t}/g:files/f:${p.path}`,node:{kind:"file",module:d,path:p.path},label:p.path,icon:"file",dirty:l.has(p.path)}))})}return u}function gi(t){const{t:i}=t,n=i("devStudio.explorer.noPackage","No package"),a=t.workspaces.map(c=>{const l=t.modulesByWs[c.id]??[],r=`w:${c.id}`;return{id:r,node:{kind:"workspace",workspaceId:c.id},label:c.label,icon:Ee(c.icon,"folder"),info:String(l.length),readOnly:c.readOnly,search:c.id,children:It(c.id,t.packagesByWs[c.id],l).map(p=>{const m=`${r}/p:${p.id}`,g=l.filter(f=>(f.packageId??xe)===p.id).sort((f,v)=>f.label.localeCompare(v.label));return{id:m,node:{kind:"package",workspaceId:c.id,packageId:p.id===xe?void 0:p.id},label:p.id===xe?n:p.label||p.id,icon:Ee(p.icon,"archive"),info:String(g.length),search:p.id,children:g.map(f=>{var S;const v=X(f),k=t.modules[v],N=`${m}/m:${f.id}`,E=k?yi(N,k,t):void 0,M=k?[...Ze(k).map(y=>`${y.entity.name??""} ${Qe(y.entity)}`),...k.documents.filter(y=>y.kind.editor==="views").flatMap(y=>pe(k,y).map(w=>`${w.key} ${w.label}`))]:[];return{id:N,node:{kind:"module",module:{workspaceId:f.workspaceId,id:f.id}},label:f.label,icon:Ee(f.icon,"box"),info:f.version,readOnly:f.readOnly,shadowedBy:f.shadowedBy,dirty:k==null?void 0:k.dirty,issues:(S=t.issueCounts)==null?void 0:S[v],search:[f.id,f.description??"",f.search??"",...M].join(" "),children:E}})}})}});if(t.templates){const c=new Map;for(const p of t.workspaces)for(const m of t.modulesByWs[p.id]??[])c.has(m.id)||c.set(m.id,m);const l=new Map;for(const p of t.templates){const m=p.category??"";l.set(m,[...l.get(m)??[],p])}const r=p=>{var m,g;return((m=p.translations.en)==null?void 0:m.name)??((g=Object.values(p.translations)[0])==null?void 0:g.name)??p.id};a.push({id:Me,node:{kind:"templates"},label:i("devStudio.tree.templates","Templates"),icon:"layers",info:String(t.templates.length),children:[...l.entries()].sort(([p],[m])=>p.localeCompare(m)).map(([p,m])=>{const g=`${Me}/c:${p}`;return{id:g,node:{kind:"category",category:p},label:p||i("devStudio.explorer.noCategory","Other"),icon:"folder",info:String(m.length),children:[...m].sort((f,v)=>(f.sortOrder??0)-(v.sortOrder??0)||r(f).localeCompare(r(v))).map(f=>{const v=`${g}/t:${f.id}`;return{id:v,node:{kind:"template",templateId:f.id},label:r(f),icon:Ee(f.icon,"layers"),info:String(f.modules.length),readOnly:f.readOnly,search:`${f.id} ${(f.tags??[]).join(" ")}`,children:f.modules.map(k=>{const N=c.get(k.moduleId);return{id:`${v}/m:${k.moduleId}`,node:{kind:"templateModule",templateId:f.id,moduleId:k.moduleId,target:N?{workspaceId:N.workspaceId,id:N.id}:void 0},label:(N==null?void 0:N.label)??k.moduleId,icon:"box",info:k.required?i("devStudio.template.required","required"):void 0,missing:!N,search:k.moduleId}})}})}})})}const d=new Map,s=new Map,o=new Map,u=(c,l,r=0)=>{for(const p of c){p.depth=r,d.set(p.id,p),l&&s.set(p.id,l);const m=Nt(p.node);o.has(m)||o.set(m,p.id),p.children&&u(p.children,p.id,r+1)}};return u(a),{rows:a,byId:d,parentOf:s,rowOfNode:o}}function ht(t,i){const n=[];let a=i;for(;a;){const d=t.byId.get(a);if(!d)break;n.unshift(d),a=t.parentOf.get(a)}return n}const qe=(t,i)=>t.rowOfNode.get(Nt(i));function $e(t){return"module"in t?t.module:void 0}function xi(t,i){var a;const n="module"in t?i.modules[X(t.module)]:void 0;switch(t.kind){case"module":return n!=null&&n.documents.some(d=>d.kind.editor==="manifest")?{kind:"manifest",module:t.module}:void 0;case"entity":return{kind:"entity",module:t.module,docKey:t.docKey,index:t.index};case"item":{const d=n&&me(n,t.docKey),s=d&&pe(n,d).find(o=>o.key===t.itemKey);return(s==null?void 0:s.definition)!==void 0||i.advanced?{...t}:void 0}case"document":{const d=n&&me(n,t.docKey);return(d==null?void 0:d.model)!==void 0?{kind:"document",module:t.module,docKey:t.docKey}:d&&i.advanced?{kind:"file",module:t.module,path:d.paths[0]}:void 0}case"panel":return{kind:"panel",module:t.module,panelKey:t.panelKey};case"file":return{kind:"file",module:t.module,path:t.path};case"package":{const d=(a=i.packages)==null?void 0:a.find(s=>s.id===t.packageId);return d&&!d.derived?{kind:"package",pkg:d}:void 0}case"template":return{kind:"template",templateId:t.templateId};default:return}}function ft(t){switch(t.kind){case"manifest":case"problems":case"history":return{kind:"module",module:t.module};case"entity":return{kind:"entity",module:t.module,docKey:t.docKey,index:t.index};case"item":return{...t};case"document":return{kind:"document",module:t.module,docKey:t.docKey};case"panel":return{kind:"panel",module:t.module,panelKey:t.panelKey};case"file":return{kind:"file",module:t.module,path:t.path};case"package":return{kind:"package",workspaceId:t.pkg.workspaceId,packageId:t.pkg.id};case"template":return t.templateId?{kind:"template",templateId:t.templateId}:void 0}}const ki=/^\/(?:[A-Za-z]+\/)?(\d+)(?:\/|$)/;function Tt(t,i){const n=t.key,a=i.path?t.documents.find(u=>u.paths.includes(i.path)):void 0;if(!a)return{kind:"module",module:n};const d=wt(a),s=a.paths.length===1?ki.exec(i.pointer??""):null,o=s?Number(s[1]):-1;if(d==="entities"){const u=ne(t,a);return Array.isArray(u)&&o>=0&&o<u.length?{kind:"entity",module:n,docKey:a.key,index:o}:{kind:"group",module:n,group:d}}if(d==="views"||d==="workflows"||d==="dataSources"){const u=o>=0?pe(t,a)[o]:void 0;return u?{kind:"item",module:n,group:d,docKey:a.key,itemKey:u.key}:{kind:"group",module:n,group:d}}return d?{kind:"document",module:n,docKey:a.key}:a.kind.editor==="manifest"?{kind:"module",module:n}:{kind:"file",module:n,path:a.paths[0]}}function vt(t){var l,r;const{module:i,doc:n,preset:a,session:d,locales:s,readOnly:o}=t,u=ne(i,n),c=p=>d.setDraft(i.key,n.key,p);switch(n.kind.editor){case"manifest":return e.jsx(bi,{...t});case"i18n":{const p=u??{};return e.jsx(Xe,{value:p,onChange:c,locales:[...new Set([...s,...Object.keys(p)])],allowEditLocales:!0,allowEditKeys:!0,highlightMissing:!0,readOnly:o})}case"permissions":return e.jsx(ji,{value:u??{permissions:[],groups:[]},onChange:c,readOnly:o});case"seeds":return e.jsx(Ni,{value:u??{seeds:{}},onChange:c,entities:Ve(i),readOnly:o});case"rbac":return e.jsx(h.NiceAccessManager,{value:u,onChange:c,readOnly:o});case"hooks":return e.jsx(h.NiceLifecycleHooksEditor,{triggers:((l=a.hooks)==null?void 0:l.triggers)??[],handlers:(r=a.hooks)==null?void 0:r.handlers,bindings:u??[],onChange:c,groupByTrigger:!0,allowCondition:!0,readOnly:o});case"script":return t.scriptRunner?e.jsx(h.NiceScriptRunner,{...t.scriptRunner,value:String(u??""),onChange:c}):e.jsx(h.NiceSimpleCodeEditor,{value:String(u??""),onChange:c,language:"javascript",height:"100%",lineNumbers:!0,readOnly:o});case"text":return e.jsx(h.NiceSimpleCodeEditor,{value:String(u??""),onChange:c,height:"100%",lineNumbers:!0,readOnly:o});default:return e.jsx(Ye,{value:u,onChange:c,readOnly:o,height:"100%",label:n.label})}}function bi({module:t,doc:i,preset:n,session:a,readOnly:d,advanced:s}){var M;const{t:o}=h.useNiceTranslation(),u=ne(t,i),c=x.useMemo(()=>u??{},[u]),l=S=>a.setDraft(t.key,i.key,S),r=n.manifestSections,p=x.useMemo(()=>(r??[]).map(S=>D.fitManifestSection(S,c)),[r,c]),m=r??[],g=x.useMemo(()=>new Set(p.flatMap(S=>S.keys)),[p]),f=Object.keys(c).filter(S=>!g.has(S)),[v,k]=x.useState(((M=p[0])==null?void 0:M.section.id)??"__other"),N=p.find(S=>S.section.id===v),E=s?e.jsx(Ye,{value:Object.fromEntries(f.map(S=>[S,c[S]])),readOnly:d,label:o("devStudio.manifest.other","Other properties"),onChange:S=>{if(S&&typeof S=="object"&&!Array.isArray(S)){const y=Object.fromEntries(Object.entries(c).filter(([w])=>g.has(w)));l({...y,...S})}}}):e.jsxs("div",{className:"nice-development-studio__note",children:[e.jsx("p",{children:o("devStudio.manifest.kept","These properties have no form here. Saving keeps them exactly as they are; switch to the advanced mode to edit them.")}),e.jsx("ul",{className:"nice-development-studio__chips",children:f.map(S=>e.jsx("li",{className:"nice-development-studio__tag",children:S},S))})]});return e.jsxs("div",{className:"nice-development-studio__sections","data-testid":"studio-manifest-form",children:[e.jsxs("nav",{className:"nice-development-studio__section-nav","aria-label":o("devStudio.manifest.sections","Sections"),children:[p.map(({section:S})=>e.jsx(h.NiceButton,{size:"sm",variant:v===S.id?"primary":"ghost","aria-pressed":v===S.id,onClick:()=>k(S.id),children:S.title},S.id)),f.length>0&&e.jsx(h.NiceButton,{size:"sm",variant:v==="__other"?"primary":"ghost","aria-pressed":v==="__other",onClick:()=>k("__other"),children:`${o("devStudio.manifest.other","Other properties")} (${f.length})`})]}),e.jsx("div",{className:"nice-development-studio__section-body",children:N?e.jsx(we,{schema:N.section.schema,fields:N.section.fields,uiSchema:N.section.uiSchema,value:Object.fromEntries(N.keys.filter(S=>S in c).map(S=>[S,c[S]])),onChange:S=>{const y={...c};for(const w of N.keys)S[w]===void 0?delete y[w]:y[w]=S[w];l(y)},readOnly:d}):f.length>0||m.length===0?E:null})]})}function ji({value:t,onChange:i,readOnly:n}){const{t:a}=h.useNiceTranslation(),d={code:a("devStudio.permissions.code","Code"),name:a("devStudio.permissions.name","Name"),description:a("devStudio.permissions.description","Description")},s=x.useMemo(()=>{const u={};for(const c of t.groups)for(const l of c.permissions)u[`${c.id}:${l}`]=!0;return u},[t.groups]),o=(u,c)=>{const l=t.permissions[u],r={...l,...c};i({permissions:t.permissions.map((p,m)=>m===u?r:p),groups:c.code!==void 0&&c.code!==l.code?t.groups.map(p=>({...p,permissions:p.permissions.map(m=>m===l.code?r.code:m)})):t.groups})};return e.jsxs("div",{className:"nice-development-studio__permissions",children:[e.jsx("h4",{children:a("devStudio.permissions.codes","Permissions")}),e.jsxs("table",{className:"nice-development-studio__table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:d.code}),e.jsx("th",{children:d.name}),e.jsx("th",{children:d.description}),!n&&e.jsx("th",{"aria-label":a("devStudio.delete","Delete")})]})}),e.jsx("tbody",{children:t.permissions.map((u,c)=>e.jsxs("tr",{children:[["code","name","description"].map(l=>e.jsx("td",{children:e.jsx("input",{className:"nice-development-studio__cell",value:u[l]??"",readOnly:n,"aria-label":`${d[l]} ${u.code}`,onChange:r=>o(c,{[l]:r.target.value})})},l)),!n&&e.jsx("td",{children:e.jsx(h.NiceButton,{size:"sm",variant:"ghost",ariaLabel:`${a("devStudio.delete","Delete")} ${u.code}`,onClick:()=>i({permissions:t.permissions.filter((l,r)=>r!==c),groups:t.groups.map(l=>({...l,permissions:l.permissions.filter(r=>r!==u.code)}))}),children:e.jsx(h.NiceIcon,{name:"trash",size:14})})})]},c))})]}),!n&&e.jsxs("div",{className:"nice-development-studio__row",children:[e.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:e.jsx(h.NiceIcon,{name:"plus",size:14}),onClick:()=>i({...t,permissions:[...t.permissions,{code:`New.Permission${t.permissions.length+1}`}]}),children:a("devStudio.permissions.addCode","New permission")}),e.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:e.jsx(h.NiceIcon,{name:"plus",size:14}),onClick:()=>i({...t,groups:[...t.groups,{id:`group${t.groups.length+1}`,label:a("devStudio.permissions.newGroup","Group {n}").replace("{n}",String(t.groups.length+1)),permissions:[]}]}),children:a("devStudio.permissions.addGroup","New group")})]}),e.jsx("h4",{children:a("devStudio.permissions.groups","Groups")}),e.jsx(h.NicePermissionMatrix,{roles:t.groups.map(u=>({id:u.id,label:u.label})),actions:t.permissions.map(u=>({id:u.code,label:u.name||u.code})),value:s,readOnly:n,showBulkActions:!0,onChange:u=>i({...t,groups:t.groups.map(c=>({...c,permissions:t.permissions.map(l=>l.code).filter(l=>u[`${c.id}:${l}`]===!0)}))})})]})}const yt=t=>t===null||typeof t!="object";function Si(t){const i=t.toLowerCase();return/(int|long|decimal|double|float|number|money)/.test(i)?"number":/bool/.test(i)?"boolean":"string"}function wi(t,i){const n={},a=Array.isArray(i==null?void 0:i.fields)?i.fields:[];for(const d of a){const s=String(d.name??"");s&&t.every(o=>yt(o[s]))&&(n[s]={type:Si(String(d.dataType??d.type??"string")),title:String(d.displayName||s)})}for(const d of t)for(const[s,o]of Object.entries(d))!(s in n)&&t.every(u=>yt(u[s]))&&(n[s]={type:typeof o=="number"?"number":typeof o=="boolean"?"boolean":"string",title:s});return{type:"object",properties:n}}function Ni({value:t,onChange:i,entities:n,readOnly:a}){const{t:d}=h.useNiceTranslation(),s=u=>n.find(c=>c.name===u||c.tableName===u),o=u=>{const c=t[u]??{},l=Object.keys(c);return l.length===0?e.jsx("p",{className:"nice-development-studio__muted",children:d("devStudio.seeds.empty","No rows.")}):e.jsx(h.NiceTabs,{tabs:l.map(r=>{const p=c[r];return{id:r,label:`${r} (${p.length})`,content:e.jsx(Ue,{value:p,itemSchema:wi(p,s(r)),title:r,readOnly:a,onChange:m=>{const g=m.length===p.length?m.map((f,v)=>f===p[v]?f:{...p[v],...f}):m;i({...t,[u]:{...c,[r]:g}})}})}})})};return e.jsx(h.NiceTabs,{tabs:[{id:"seeds",label:d("devStudio.seeds.data","Data"),content:o("seeds")},{id:"demo",label:d("devStudio.seeds.demo","Demo data"),content:o("demoSeeds")}]})}function _i({module:t,path:i,session:n,readOnly:a}){var r;const{t:d}=h.useNiceTranslation(),[s,o]=x.useState("source"),u=t.changes.find(p=>p.path===i),c=t.documents.filter(p=>p.paths.includes(i)).map(p=>p.key),l=((r=t.files.find(p=>p.path===i))==null?void 0:r.text)??"";return e.jsxs("div",{className:"nice-development-studio__source","data-testid":"studio-file-source",children:[e.jsx("div",{className:"nice-development-studio__row",children:e.jsxs("div",{className:"nice-development-studio__segmented",role:"group","aria-label":d("devStudio.doc.mode","Show"),children:[e.jsx(h.NiceButton,{size:"sm",variant:s==="source"?"primary":"ghost","aria-pressed":s==="source",onClick:()=>o("source"),children:d("devStudio.doc.source","Source")}),e.jsx(h.NiceButton,{size:"sm",variant:s==="changes"?"primary":"ghost","aria-pressed":s==="changes",onClick:()=>o("changes"),children:`${d("devStudio.doc.changes","Changes")}${u?" (1)":""}`})]})}),s==="source"?e.jsx(h.NiceSimpleCodeEditor,{value:t.pending.get(i)??"",language:i.endsWith(".json")?"json":i.endsWith(".js")?"javascript":"plaintext",height:"100%",lineNumbers:!0,readOnly:a,onChange:p=>n.setRaw(t.key,i,D.keepTextFormat(p,t.pending.get(i)),c)}):u?e.jsx(jt,{before:l,after:u.type==="write"?u.text:""}):e.jsx("p",{className:"nice-development-studio__muted",children:d("devStudio.diff.none","No changes.")})]})}const Ii=t=>({type:"object",required:["id"],properties:{id:{type:"string",title:t("devStudio.template.id","Id (slug)")},category:{type:"string",title:t("devStudio.template.category","Category")},subCategory:{type:"string",title:t("devStudio.template.subCategory","Subcategory")},parentId:{type:"string",title:t("devStudio.template.parent","Parent template")},icon:{type:"string",title:t("devStudio.template.icon","Icon")},sortOrder:{type:"number",title:t("devStudio.template.sortOrder","Order")},tags:{type:"array",items:{type:"string"},title:t("devStudio.template.tags","Tags")}}});function Ti({session:t,template:i,locales:n,extraSchema:a,readOnly:d,onSaved:s,onDeleted:o}){var S;const{t:u}=h.useNiceTranslation(),[c,l]=x.useState(()=>i??{id:"",translations:{[n[0]??"en"]:{name:""}},modules:[]}),[r,p]=x.useState(null),m=d||!!(i!=null&&i.readOnly),g={id:c.id,category:c.category,subCategory:c.subCategory,parentId:c.parentId,icon:c.icon,sortOrder:c.sortOrder,tags:c.tags},f=Object.fromEntries(Object.entries(c.translations).map(([y,w])=>[y,{name:w.name,description:w.description??""}])),v=x.useMemo(()=>t.workspaces.map(y=>{const w=t.modulesByWs[y.id]??[],_=[...new Set(w.map(O=>O.packageId??""))].sort();return{id:`w:${y.id}`,label:y.label,kind:"workspace",children:_.map(O=>({id:`w:${y.id}/p:${O}`,label:O||u("devStudio.explorer.noPackage","No package"),kind:"package",children:w.filter(B=>(B.packageId??"")===O).map(B=>({id:`m:${B.id}`,label:B.label,kind:"module"}))}))}}),[t.workspaces,t.modulesByWs,u]),k=x.useMemo(()=>{const y=new Map;for(const w of Object.values(t.modulesByWs))for(const _ of w)y.set(_.id,_.label);return y},[t.modulesByWs]),N=y=>l({...c,modules:y}),E=(y,w)=>{const _=[...c.modules],[O]=_.splice(y,1);_.splice(y+w,0,O),N(_)},M=[{field:"label",header:u("devStudio.explorer.name","Name")}];return e.jsxs("div",{className:"nice-development-studio__template","data-testid":"studio-template-editor",children:[e.jsxs("div",{className:"nice-development-studio__doc-bar",children:[e.jsx(h.NiceIcon,{name:"layers",size:14}),e.jsx("strong",{className:"nice-development-studio__doc-title",children:i?((S=c.translations.en)==null?void 0:S.name)||c.id:u("devStudio.template.new","New template")}),e.jsx("span",{className:"nice-development-studio__spacer"}),!m&&e.jsx(h.NiceButton,{size:"sm",variant:"primary",disabled:!c.id.trim(),onClick:async()=>{p(null);const y=await t.saveTemplate({...c,id:c.id.trim()},i==null?void 0:i.id);y?s==null||s(y):p(u("devStudio.template.saveFailed","The template could not be saved; see the output panel."))},children:u("devStudio.save","Save")}),!m&&i&&e.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:e.jsx(h.NiceIcon,{name:"trash",size:14}),onClick:async()=>{await t.deleteTemplate(i.id)&&(o==null||o())},children:u("devStudio.delete","Delete")})]}),r&&e.jsx("p",{className:"nice-development-studio__error",role:"alert",children:r}),e.jsxs("div",{className:"nice-development-studio__columns",children:[e.jsxs("section",{children:[e.jsx("h4",{children:u("devStudio.template.basics","Template")}),e.jsx(we,{schema:Ii(u),value:g,readOnly:m,onChange:y=>l({...c,id:String(y.id??""),category:y.category||void 0,subCategory:y.subCategory||void 0,parentId:y.parentId||void 0,icon:y.icon||void 0,sortOrder:typeof y.sortOrder=="number"?y.sortOrder:void 0,tags:Array.isArray(y.tags)?y.tags:void 0})}),a&&e.jsx(we,{schema:a,value:c.extra??{},readOnly:m,onChange:y=>l({...c,extra:y})}),e.jsx("h4",{children:u("devStudio.template.translations","Name and description")}),e.jsx(Xe,{value:f,locales:[...new Set([...n,...Object.keys(f)])],allowEditLocales:!0,readOnly:m,onChange:y=>l({...c,translations:Object.fromEntries(Object.entries(y).map(([w,_])=>[w,{name:_.name??"",..._.description?{description:_.description}:{}}]))})})]}),e.jsxs("section",{children:[e.jsx("h4",{children:u("devStudio.template.modules","Modules")}),e.jsx(h.NiceTreeGrid,{data:v,nested:!0,keyField:"id",childrenField:"children",columns:M,sortable:!1,compact:!0,checkable:!0,checkStrategy:"leaves",isRowCheckable:y=>y.kind!=="workspace",isRowDisabled:()=>m,checkedKeys:c.modules.map(y=>`m:${y.moduleId}`),onCheckedChange:y=>{const w=y.filter(B=>B.startsWith("m:")).map(B=>B.slice(2)),_=c.modules.filter(B=>w.includes(B.moduleId)),O=w.filter(B=>!_.some(P=>P.moduleId===B)).map(B=>({moduleId:B}));N([..._,...O])},checkedSummary:y=>u("devStudio.template.summary","{count} modules · {required} required").replace("{count}",String(y.checked)).replace("{required}",String(c.modules.filter(w=>w.required).length)),searchable:!0,searchFields:["label"],virtualScroll:!0,height:320,"aria-label":u("devStudio.template.modules","Modules")}),e.jsxs("table",{className:"nice-development-studio__table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:u("devStudio.template.module","Module")}),e.jsx("th",{children:u("devStudio.template.required","required")}),e.jsx("th",{children:u("devStudio.template.condition","Condition")}),!m&&e.jsx("th",{"aria-label":u("devStudio.template.order","Order")})]})}),e.jsx("tbody",{children:c.modules.map((y,w)=>e.jsxs("tr",{children:[e.jsx("td",{children:k.get(y.moduleId)??y.moduleId}),e.jsx("td",{children:e.jsx("input",{type:"checkbox",checked:!!y.required,disabled:m,"aria-label":`${u("devStudio.template.required","required")} ${y.moduleId}`,onChange:_=>N(c.modules.map((O,B)=>B===w?{...O,required:_.target.checked}:O))})}),e.jsx("td",{children:e.jsx("input",{className:"nice-development-studio__cell",value:y.condition??"",readOnly:m,"aria-label":`${u("devStudio.template.condition","Condition")} ${y.moduleId}`,onChange:_=>N(c.modules.map((O,B)=>B===w?{...O,condition:_.target.value||void 0}:O))})}),!m&&e.jsxs("td",{className:"nice-development-studio__nowrap",children:[e.jsx(h.NiceButton,{size:"sm",variant:"ghost",disabled:w===0,ariaLabel:u("devStudio.template.up","Move up"),onClick:()=>E(w,-1),children:e.jsx(h.NiceIcon,{name:"chevron-up",size:12})}),e.jsx(h.NiceButton,{size:"sm",variant:"ghost",disabled:w===c.modules.length-1,ariaLabel:u("devStudio.template.down","Move down"),onClick:()=>E(w,1),children:e.jsx(h.NiceIcon,{name:"chevron-down",size:12})})]})]},y.moduleId))})]})]})]})]})}function Ci({session:t,pkg:i,readOnly:n,onNewModule:a,onOpenModule:d}){const{t:s}=h.useNiceTranslation(),[o,u]=x.useState({id:i.id,label:i.label,description:i.description,icon:i.icon}),c=(t.modulesByWs[i.workspaceId]??[]).filter(r=>r.packageId===i.id),l=!n&&!i.derived&&!i.readOnly;return e.jsxs("div",{className:"nice-development-studio__template","data-testid":"studio-package-editor",children:[e.jsxs("div",{className:"nice-development-studio__doc-bar",children:[e.jsx(h.NiceIcon,{name:"archive",size:14}),e.jsx("strong",{className:"nice-development-studio__doc-title",children:i.label||i.id}),e.jsx("span",{className:"nice-development-studio__spacer"}),!n&&e.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:e.jsx(h.NiceIcon,{name:"plus",size:14}),onClick:a,children:s("devStudio.package.newModule","New module here")}),l&&e.jsx(h.NiceButton,{size:"sm",variant:"primary",onClick:()=>void t.savePackage({...i,id:String(o.id??i.id),label:String(o.label??""),description:o.description||void 0,icon:o.icon||void 0}),children:s("devStudio.save","Save")})]}),i.derived?e.jsx("p",{className:"nice-development-studio__muted",children:s("devStudio.package.derived","This package comes from the modules themselves (their category); rename it by changing their manifests.")}):e.jsx(we,{schema:{type:"object",required:["id","label"],properties:{id:{type:"string",title:s("devStudio.package.id","Id")},label:{type:"string",title:s("devStudio.package.label","Name")},description:{type:"string",title:s("devStudio.package.description","Description")},icon:{type:"string",title:s("devStudio.template.icon","Icon")}}},value:o,readOnly:!l,onChange:r=>u(r)}),e.jsx("h4",{children:s("devStudio.template.modules","Modules")}),e.jsxs("ul",{className:"nice-development-studio__list",children:[c.map(r=>e.jsxs("li",{children:[e.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:e.jsx(h.NiceIcon,{name:"box",size:14}),onClick:()=>d(r.id),children:r.label}),r.description&&e.jsx("span",{className:"nice-development-studio__muted",children:r.description})]},r.id)),c.length===0&&e.jsx("li",{className:"nice-development-studio__muted",children:s("devStudio.explorer.empty","No modules.")})]})]})}const Ei=t=>"module"in t?t.module:void 0;function $i(t){const{screen:i,crumbs:n,session:a,readOnly:d,tutorialButton:s,onBack:o,onSave:u}=t,{t:c}=h.useNiceTranslation(),l=Ei(i),r=l?a.modules[X(l)]:void 0,p=d(l),m=Mi(i,r,a);return e.jsxs("div",{className:"nice-development-studio__edit","data-testid":"studio-edit-screen",children:[e.jsxs("header",{className:"nice-development-studio__edit-header",children:[e.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:e.jsx(h.NiceIcon,{name:"arrow-left",size:14}),onClick:o,"data-testid":"studio-back",children:c("devStudio.edit.back","Back")}),e.jsx(h.NiceBreadcrumb,{className:"nice-development-studio__crumbs",size:"sm",separator:"›",items:n}),e.jsx("span",{className:"nice-development-studio__spacer"}),m&&!p&&e.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:e.jsx(h.NiceIcon,{name:"trash",size:14}),onClick:()=>{m(),o()},children:c("devStudio.delete","Delete")}),r&&e.jsxs(e.Fragment,{children:[e.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:e.jsx(h.NiceIcon,{name:"check",size:14}),onClick:()=>void a.validate(r.key),children:c("devStudio.validate","Validate")}),!p&&e.jsxs(e.Fragment,{children:[e.jsx(h.NiceButton,{size:"sm",variant:"ghost",disabled:!r.dirty,onClick:()=>a.discard(r.key),children:c("devStudio.discard","Discard changes")}),e.jsx(h.NiceButton,{size:"sm",variant:"primary",disabled:!r.dirty,onClick:()=>u(r.key),"data-tour":"devstudio-save",children:r.dirty?c("devStudio.saveCount","Save ({count})").replace("{count}",String(r.changes.length)):c("devStudio.save","Save")})]})]}),s]}),e.jsx("div",{className:"nice-development-studio__edit-body",children:e.jsx(Ki,{...t,module:r,readOnlyHere:p})})]})}function Mi(t,i,n){if(!i||t.kind!=="entity"&&t.kind!=="item")return;const a=me(i,t.docKey);if(!a)return;if(t.kind==="entity"){const s=ne(i,a);return Array.isArray(s)?()=>n.setDraft(i.key,a.key,et(s,t.index,null)):void 0}if(t.group==="dataSources"){const s=ne(i,a)??[];return()=>n.setDraft(i.key,a.key,s.filter(o=>o.key!==t.itemKey))}const d=pe(i,a);return()=>n.setDraft(i.key,a.key,_t(d,t.itemKey,null))}function he(){const{t}=h.useNiceTranslation();return e.jsx("p",{className:"nice-development-studio__muted",children:t("devStudio.edit.gone","This is no longer in the module.")})}function Ki(t){var r,p,m,g,f;const{screen:i,module:n,session:a,preset:d,provider:s,locales:o,advanced:u,readOnlyHere:c}=t,{t:l}=h.useNiceTranslation();if(i.kind==="package")return e.jsx(Ci,{session:a,pkg:i.pkg,readOnly:t.readOnly(),onNewModule:()=>t.onNewModule({workspaceId:i.pkg.workspaceId,packageId:i.pkg.id}),onOpenModule:v=>t.onReveal({kind:"module",module:{workspaceId:i.pkg.workspaceId,id:v}})});if(i.kind==="template"){const v=i.templateId?(r=a.templates)==null?void 0:r.find(k=>k.id===i.templateId):void 0;return e.jsx(Ti,{session:a,template:v,locales:o,extraSchema:d.templateSchema,readOnly:t.readOnly(),onSaved:k=>{k.id!==i.templateId&&t.onScreen({kind:"template",templateId:k.id})},onDeleted:t.onBack},i.templateId??"new")}if(!n)return e.jsx("p",{className:"nice-development-studio__muted",children:l("devStudio.loading","Loading…")});switch(i.kind){case"manifest":{const v=n.documents.find(k=>k.kind.editor==="manifest");return v?e.jsx(vt,{module:n,doc:v,preset:d,session:a,locales:o,readOnly:c,advanced:u,scriptRunner:t.scriptRunner}):e.jsx(he,{})}case"entity":{const v=me(n,i.docKey),k=v?ne(n,v):void 0,N=Array.isArray(k)?k[i.index]:void 0;return!v||!k||!N?e.jsx(he,{}):e.jsx(He,{value:N,onChange:E=>a.setDraft(n.key,v.key,et(k,i.index,E)),entityMetaSchema:(p=d.entities)==null?void 0:p.entityMetaSchema,fieldSchema:(m=d.entities)==null?void 0:m.fieldSchema,fieldsKey:(g=d.entities)==null?void 0:g.fieldsKey,readOnly:c,"data-testid":"studio-entity-form"})}case"item":return e.jsx(Oi,{...t,screen:i,module:n});case"document":{const v=me(n,i.docKey);return v?e.jsx(vt,{module:n,doc:v,preset:d,session:a,locales:o,readOnly:c,advanced:u,scriptRunner:t.scriptRunner}):e.jsx(he,{})}case"panel":{const v=(f=t.modulePanels)==null?void 0:f.call(t,{module:n.key,files:n.working,dirty:n.dirty}).find(k=>k.key===i.panelKey);return v?e.jsx(e.Fragment,{children:v.content}):e.jsx(he,{})}case"file":return n.working.some(v=>v.path===i.path)?e.jsx(_i,{module:n,path:i.path,session:a,readOnly:c}):e.jsx(he,{});case"problems":return e.jsx(Fi,{module:n,issues:t.issues(n.key),onReveal:t.onReveal});case"history":return e.jsx(Bi,{module:n,provider:s,session:a,readOnly:c})}}function Oi({screen:t,module:i,session:n,readOnlyHere:a,advanced:d,renderViewPreview:s,onScreen:o}){const{t:u}=h.useNiceTranslation(),c=me(i,t.docKey);if(!c)return e.jsx(he,{});if(t.group==="dataSources"){const f=ne(i,c)??[],v=f.find(k=>k.key===t.itemKey);return v?e.jsx(h.NiceDataSourceBuilder,{value:v,schemas:D.entitiesToSchemas(Ve(i)),onChange:k=>{n.setDraft(i.key,c.key,f.map(N=>N.key===v.key?k:N)),k.key!==v.key&&o({...t,itemKey:k.key})}}):e.jsx(he,{})}const l=pe(i,c),r=l.find(f=>f.key===t.itemKey);if(!r)return e.jsx(he,{});const p=f=>{n.setDraft(i.key,c.key,_t(l,r.key,f)),f.key!==r.key&&o({...t,itemKey:f.key})},m=f=>p({...r,definition:f,label:f.name||r.label,key:f.id&&!l.some(v=>v!==r&&v.key===f.id)?f.id:r.key});if(r.definition===void 0)return d?e.jsxs("div",{className:"nice-development-studio__source",children:[e.jsxs("p",{className:"nice-development-studio__muted",children:[u("devStudio.items.rawReason","The editor does not know this shape, so it is edited as JSON."),r.rawReason?` (${r.rawReason})`:""]}),e.jsx(Ye,{value:r.source,readOnly:a,label:r.label,height:"100%",onChange:f=>p({...r,source:f})})]}):e.jsx("p",{className:"nice-development-studio__muted",children:u("devStudio.preview.noDesigner","There is no designer for this kind of entry yet.")});if(t.group==="workflows")return e.jsx(h.NiceWorkflowDesigner,{workflow:r.definition,onChange:f=>m(f),readOnly:a});const g=e.jsx(h.NiceViewEditor,{value:r.definition,onChange:f=>m(f),entities:Ve(i),dataSourceOptions:i.documents.filter(f=>f.kind.editor==="dataSources").flatMap(f=>ne(i,f)??[]).map(f=>({key:f.key,label:f.label})),height:640});return s?e.jsx(h.NiceTabs,{tabs:[{id:"design",label:u("devStudio.view.design","Design"),content:g},{id:"preview",label:u("devStudio.view.hostPreview","Preview in the app"),content:s({module:i.key,item:r,files:i.working})}]}):g}function Fi({module:t,issues:i,onReveal:n}){const{t:a}=h.useNiceTranslation();return i.length===0?e.jsx("p",{className:"nice-development-studio__muted",children:a("devStudio.overview.noProblems","No problems found.")}):e.jsx("ul",{className:"nice-development-studio__issues","data-testid":"studio-problems",children:i.map((d,s)=>e.jsxs("li",{className:`nice-development-studio__issue nice-development-studio__issue--${d.severity}`,children:[e.jsx(h.NiceIcon,{name:d.severity==="error"?"error":d.severity==="warning"?"warning":"info",size:14}),e.jsx("span",{children:Ct(a,d)}),d.path&&e.jsx("span",{className:"nice-development-studio__muted",children:d.path}),e.jsx(h.NiceButton,{size:"sm",variant:"ghost",onClick:()=>n(Tt(t,d)),children:a("devStudio.problems.goTo","Go to")})]},s))})}function Ct(t,i){return i.messageKey?Object.entries(i.params??{}).reduce((n,[a,d])=>n.replace(`{${a}}`,String(d)),t(i.messageKey,i.message)):i.message}function Bi({module:t,provider:i,session:n,readOnly:a}){const[d,s]=x.useState(null),o=t.key;return x.useEffect(()=>{let u=!0;return i!=null&&i.listRevisions&&i.listRevisions(o).then(c=>{u&&s(c.map(l=>({id:l.id,label:l.label,author:l.author,timestamp:l.timestamp,summary:l.summary})))}).catch(()=>s([])),()=>{u=!1}},[i,o,t.files]),e.jsx(h.NiceRevisionHistory,{revisions:d??[],language:"json",loadContent:i!=null&&i.readRevision?u=>i.readRevision(o,u):void 0,onRollback:i!=null&&i.rollback&&!a?async u=>{await i.rollback(o,u),await n.reload(o)}:void 0})}function ie({icon:t,title:i,subtitle:n,badges:a,actions:d,children:s}){return e.jsxs("section",{className:"nice-development-studio__preview","data-testid":"studio-preview",children:[e.jsxs("div",{className:"nice-development-studio__preview-info",children:[e.jsxs("header",{className:"nice-development-studio__preview-head",children:[e.jsx(h.NiceIcon,{name:t,size:20}),e.jsxs("div",{className:"nice-development-studio__preview-name",children:[e.jsx("h3",{className:"nice-development-studio__preview-title",children:i}),n&&e.jsx("span",{className:"nice-development-studio__muted",children:n})]})]}),a&&e.jsx("div",{className:"nice-development-studio__preview-badges",children:a}),s]}),d&&e.jsx("footer",{className:"nice-development-studio__preview-actions",children:d})]})}function oe({items:t}){const i=t.filter(([,n])=>n!=null&&n!=="");return i.length===0?null:e.jsx("dl",{className:"nice-development-studio__facts",children:i.map(([n,a])=>e.jsxs("div",{className:"nice-development-studio__fact",children:[e.jsx("dt",{children:n}),e.jsx("dd",{children:a})]},n))})}function Se({rows:t,onSelect:i,limit:n=12}){const{t:a}=h.useNiceTranslation();return t.length===0?null:e.jsxs("ul",{className:"nice-development-studio__preview-list",children:[t.slice(0,n).map(d=>e.jsxs("li",{children:[e.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:e.jsx(h.NiceIcon,{name:d.icon,size:14}),onClick:()=>i(d.id),children:d.label}),d.info&&e.jsx("span",{className:"nice-development-studio__muted",children:d.info})]},d.id)),t.length>n&&e.jsx("li",{className:"nice-development-studio__muted",children:a("devStudio.preview.more","…and {count} more").replace("{count}",String(t.length-n))})]})}const Te=t=>Array.isArray(t)?t.length:void 0;function zi(t){var p,m,g,f;const{row:i,session:n,advanced:a,onEdit:d}=t,{t:s}=h.useNiceTranslation();if(!i)return e.jsx("div",{className:"nice-development-studio__placeholder","data-testid":"studio-preview-empty",children:t.emptyText});const o=i.node,u=o.kind==="package"?It(o.workspaceId,n.packagesByWs[o.workspaceId],n.modulesByWs[o.workspaceId]??[]):void 0,c=xi(o,{modules:n.modules,packages:u,advanced:a}),l=c?e.jsx(h.NiceButton,{size:"sm",variant:"primary",leftIcon:e.jsx(h.NiceIcon,{name:"edit",size:14}),onClick:()=>d(c),"data-testid":"studio-edit","data-tour":"devstudio-edit",children:o.kind==="module"?s("devStudio.preview.editSettings","Edit settings"):s("devStudio.preview.edit","Edit")}):null,r="module"in o?n.modules[X(o.module)]:void 0;if("module"in o&&!r)return e.jsx(ie,{icon:i.icon,title:i.label,children:e.jsx("p",{className:"nice-development-studio__muted",children:s("devStudio.loading","Loading…")})});switch(o.kind){case"workspace":return e.jsx(Di,{...t,row:i,workspaceId:o.workspaceId});case"package":return e.jsx(Pi,{...t,row:i,workspaceId:o.workspaceId,packageId:o.packageId,editButton:l});case"module":return e.jsx(Ri,{...t,row:i,module:r,editButton:l});case"group":return e.jsx(Ai,{...t,row:i,module:r,group:o.group});case"entity":return e.jsx(Vi,{...t,row:i,module:r,docKey:o.docKey,index:o.index,editButton:l});case"item":return e.jsx(Wi,{...t,row:i,module:r,node:o,editButton:l});case"document":return e.jsx(Ji,{...t,row:i,module:r,docKey:o.docKey,editButton:l});case"panel":return e.jsx(ie,{icon:i.icon,title:i.label,actions:l});case"file":{const v=r.working.find(k=>k.path===o.path);return e.jsx(ie,{icon:"file",title:i.label,actions:l,children:e.jsx(oe,{items:[[s("devStudio.preview.size","Size"),v?`${new TextEncoder().encode(v.text).length} B`:void 0],[s("devStudio.preview.state","State"),i.dirty?s("devStudio.explorer.unsaved","Unsaved changes"):void 0]]})})}case"templates":return e.jsx(ie,{icon:"layers",title:i.label,actions:(p=t.provider)!=null&&p.saveTemplate&&!t.readOnly()?e.jsx(h.NiceButton,{size:"sm",variant:"primary",leftIcon:e.jsx(h.NiceIcon,{name:"plus",size:14}),onClick:t.onNewTemplate,children:s("devStudio.preview.newTemplate","New template")}):void 0,children:e.jsx(Se,{rows:i.children??[],onSelect:t.onSelect})});case"category":return e.jsx(ie,{icon:"folder",title:i.label,children:e.jsx(Se,{rows:i.children??[],onSelect:t.onSelect})});case"template":{const v=(m=n.templates)==null?void 0:m.find(N=>N.id===o.templateId),k=(v==null?void 0:v.translations.en)??Object.values((v==null?void 0:v.translations)??{})[0];return e.jsxs(ie,{icon:i.icon,title:i.label,subtitle:v==null?void 0:v.category,actions:l,children:[(k==null?void 0:k.description)&&e.jsx("p",{children:k.description}),e.jsx(oe,{items:[["Id",v==null?void 0:v.id],[s("devStudio.preview.modules","Modules"),String((v==null?void 0:v.modules.length)??0)],[s("devStudio.preview.tags","Tags"),(g=v==null?void 0:v.tags)==null?void 0:g.join(", ")]]}),e.jsx(Se,{rows:i.children??[],onSelect:t.onSelect,limit:8})]})}case"templateModule":{const v=(f=n.templates)==null?void 0:f.find(N=>N.id===o.templateId),k=v==null?void 0:v.modules.find(N=>N.moduleId===o.moduleId);return e.jsxs(ie,{icon:"box",title:i.label,subtitle:o.moduleId,actions:o.target?e.jsx(h.NiceButton,{size:"sm",variant:"primary",leftIcon:e.jsx(h.NiceIcon,{name:"arrow-right",size:14}),onClick:()=>t.onReveal({kind:"module",module:o.target}),children:s("devStudio.preview.goToModule","Go to the module")}):void 0,children:[e.jsx(oe,{items:[[s("devStudio.preview.required","Required"),k!=null&&k.required?s("devStudio.preview.yes","yes"):void 0],[s("devStudio.preview.condition","Condition"),k==null?void 0:k.condition],[s("devStudio.preview.description","Description"),k==null?void 0:k.description]]}),i.missing&&e.jsx("p",{className:"nice-development-studio__error",children:s("devStudio.preview.missingModule","No project has this module.")})]})}}}function Di({row:t,workspaceId:i,session:n,provider:a,readOnly:d,canCreateModule:s,onSelect:o,onNewModule:u,onNewPackage:c}){var m;const{t:l}=h.useNiceTranslation(),r=n.workspaces.find(g=>g.id===i),p=!d()&&!(r!=null&&r.readOnly);return e.jsxs(ie,{icon:t.icon,title:t.label,badges:r!=null&&r.readOnly?e.jsx("span",{className:"nice-development-studio__tag",children:l("devStudio.explorer.readOnly","Read-only")}):void 0,actions:p&&(s||a!=null&&a.savePackage)?e.jsxs(e.Fragment,{children:[s&&e.jsx(h.NiceButton,{size:"sm",variant:"primary",leftIcon:e.jsx(h.NiceIcon,{name:"box",size:14}),onClick:()=>u({workspaceId:i}),children:l("devStudio.preview.newModule","New module")}),(a==null?void 0:a.savePackage)&&e.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:e.jsx(h.NiceIcon,{name:"archive",size:14}),onClick:()=>c(i),children:l("devStudio.preview.newPackage","New package")})]}):void 0,children:[(r==null?void 0:r.description)&&e.jsx("p",{children:r.description}),e.jsx(oe,{items:[[l("devStudio.preview.packages","Packages"),String(((m=t.children)==null?void 0:m.length)??0)],[l("devStudio.preview.modules","Modules"),t.info]]}),e.jsx(Se,{rows:t.children??[],onSelect:o})]})}function Pi({row:t,workspaceId:i,packageId:n,session:a,readOnly:d,canCreateModule:s,editButton:o,onSelect:u,onNewModule:c}){var g;const{t:l}=h.useNiceTranslation(),r=(g=a.packagesByWs[i])==null?void 0:g.find(f=>f.id===n),p=a.workspaces.find(f=>f.id===i),m=!d()&&!(p!=null&&p.readOnly);return e.jsxs(ie,{icon:t.icon,title:t.label,subtitle:n,actions:e.jsxs(e.Fragment,{children:[o,m&&s&&e.jsx(h.NiceButton,{size:"sm",variant:o?"ghost":"primary",leftIcon:e.jsx(h.NiceIcon,{name:"plus",size:14}),onClick:()=>c({workspaceId:i,packageId:n}),children:l("devStudio.preview.newModuleHere","New module here")})]}),children:[(r==null?void 0:r.description)&&e.jsx("p",{children:r.description}),e.jsx(Se,{rows:t.children??[],onSelect:u})]})}function Ri(t){var S;const{row:i,module:n,session:a,preset:d,provider:s,readOnly:o,editButton:u}=t,{t:c}=h.useNiceTranslation(),l=n.key,r=(S=a.modulesByWs[l.workspaceId])==null?void 0:S.find(y=>y.id===l.id),p=o(l),m=t.issues(l),g=Ze(n).length,f=n.documents.filter(y=>y.kind.editor==="views").reduce((y,w)=>y+pe(n,w).length,0),v=new Set(n.documents.filter(y=>y.kind.editor==="i18n").flatMap(y=>Object.keys(ne(n,y)??{}))),k={key:l,files:n.working,documents:n.documents},N=d.newFile?d.kinds.map(y=>{var w;return{kind:y,file:(w=d.newFile)==null?void 0:w.call(d,y.id,k)}}).filter(y=>!!y.file&&!n.working.some(w=>w.path===y.file.path)):[],E=y=>e.jsx(h.NiceIcon,{name:y,size:14}),M=[...s!=null&&s.listRevisions?[{id:"history",icon:E("clock"),label:c("devStudio.overview.history","History"),onClick:()=>t.onEdit({kind:"history",module:l})}]:[],...t.canDuplicateModule&&!o()?[{id:"duplicate",icon:E("copy"),label:c("devStudio.explorer.duplicate","Duplicate"),onClick:()=>t.onModuleAction("duplicate",l)}]:[],...s!=null&&s.saveTemplate&&a.templates&&!o()?[{id:"addToTemplate",icon:E("layers"),label:c("devStudio.explorer.addToTemplate","Add to template"),onClick:()=>t.onModuleAction("addToTemplate",l)}]:[],...p?[]:N.map(({kind:y,file:w})=>({id:`add:${y.id}`,icon:E(y.icon??"plus"),label:`${c("devStudio.preview.add","Add:")} ${y.labelKey?c(y.labelKey,y.label):y.label}`,onClick:()=>a.setRaw(l,w.path,w.text)})),...s!=null&&s.deleteModule&&!p?[{id:"sep",divider:!0},{id:"delete",icon:E("trash"),label:c("devStudio.delete","Delete"),danger:!0,onClick:()=>t.onModuleAction("delete",l)}]:[]];return e.jsxs(ie,{icon:i.icon,title:i.label,subtitle:(r==null?void 0:r.location)??l.id,badges:e.jsxs(e.Fragment,{children:[(r==null?void 0:r.readOnly)&&e.jsx("span",{className:"nice-development-studio__tag",children:c("devStudio.explorer.readOnly","Read-only")}),(r==null?void 0:r.shadowedBy)&&e.jsx("span",{className:"nice-development-studio__tag",title:r.shadowedBy,children:c("devStudio.explorer.shadowed","shadowed")})]}),actions:e.jsxs(e.Fragment,{children:[u,n.dirty&&!p&&e.jsxs(e.Fragment,{children:[e.jsx(h.NiceButton,{size:"sm",variant:"primary",leftIcon:E("save"),onClick:()=>t.onSave(l),"data-tour":"devstudio-save",children:c("devStudio.saveCount","Save ({count})").replace("{count}",String(n.changes.length))}),e.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:E("undo"),onClick:()=>a.discard(l),children:c("devStudio.discard","Discard changes")})]}),e.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:E("check"),onClick:()=>void a.validate(l),children:c("devStudio.validate","Validate")}),e.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:E(m.length===0?"success":"warning"),onClick:()=>t.onEdit({kind:"problems",module:l}),children:`${c("devStudio.overview.problems","Problems")} (${m.length})`}),M.length>0&&e.jsx(h.NiceMenu,{className:"nice-development-studio__more",variant:"ghost",size:"sm",fullWidth:!0,items:[{id:"more",icon:E("more-horizontal"),label:c("devStudio.preview.more.actions","More actions"),children:M}]})]}),children:[(r==null?void 0:r.description)&&e.jsx("p",{children:r.description}),e.jsx(oe,{items:[["Id",l.id],[c("devStudio.preview.version","Version"),r==null?void 0:r.version],[c("devStudio.preview.entities","Entities"),String(g)],[c("devStudio.preview.views","Views"),String(f)],[c("devStudio.preview.languages","Languages"),[...v].join(", ")],[c("devStudio.preview.state","State"),n.dirty?c("devStudio.status.changed","{count} changed files").replace("{count}",String(n.changes.length)):void 0]]}),m.length>0&&e.jsxs("div",{className:"nice-development-studio__preview-issues",children:[e.jsx("ul",{className:"nice-development-studio__issues",children:m.slice(0,3).map((y,w)=>e.jsx("li",{className:`nice-development-studio__issue nice-development-studio__issue--${y.severity}`,children:e.jsxs("button",{type:"button",className:"nice-development-studio__issue-link",title:c("devStudio.problems.goTo","Go to"),onClick:()=>t.onReveal(Tt(n,y)),children:[e.jsx(h.NiceIcon,{name:y.severity==="error"?"error":y.severity==="warning"?"warning":"info",size:14}),e.jsx("span",{children:Ct(c,y)})]})},w))}),m.length>3&&e.jsx("span",{className:"nice-development-studio__muted",children:c("devStudio.preview.more","…and {count} more").replace("{count}",String(m.length-3))})]})]})}function Ai({row:t,module:i,group:n,preset:a,session:d,readOnly:s,onSelect:o,onEdit:u}){const{t:c}=h.useNiceTranslation(),r=s(i.key)?void 0:Li(n,i,a,d);return e.jsx(ie,{icon:t.icon,title:t.label,actions:r?e.jsx(h.NiceButton,{size:"sm",variant:"primary",leftIcon:e.jsx(h.NiceIcon,{name:"plus",size:14}),onClick:()=>u(r.run()),"data-testid":"studio-add",children:r.label(c)}):void 0,children:e.jsx(Se,{rows:t.children??[],onSelect:o})})}function Li(t,i,n,a){var r,p;const d=t==="entities"?"entities":t==="views"?"views":t==="workflows"?"workflows":t==="dataSources"?"dataSources":void 0,s=d?i.documents.find(m=>m.kind.editor===d&&m.model!==void 0):void 0;if(!s)return;const o=i.key;if(t==="entities"){const m=ne(i,s)??[],g=((r=n.entities)==null?void 0:r.nameKey)??"name",f=((p=n.entities)==null?void 0:p.fieldsKey)??"fields";return{label:v=>v("devStudio.preview.newEntity","New entity"),run:()=>(a.setDraft(o,s.key,[...m,{[g]:`Entity${m.length+1}`,[f]:[]}]),{kind:"entity",module:o,docKey:s.key,index:m.length})}}if(t==="dataSources"){const m=ne(i,s)??[];return{label:g=>g("devStudio.items.addDataSource","New data source"),run:()=>{const g={key:`source${m.length+1}`,kind:"query",query:{tables:[],joins:[],conditions:[],sorts:[],groupBy:[],distinct:!1},sql:""};return a.setDraft(o,s.key,[...m,g]),{kind:"item",module:o,group:"dataSources",docKey:s.key,itemKey:g.key}}}}const u=pe(i,s),c=u.length+1,l=t==="views"?{id:`view-${c}`,name:`View ${c}`,version:2,columns:12,rows:[],dataSources:[]}:{id:`workflow-${c}`,name:`Workflow ${c}`,entityType:"",version:1,states:[],transitions:[]};return{label:m=>t==="views"?m("devStudio.items.addView","New view"):m("devStudio.items.addWorkflow","New workflow"),run:()=>{const m={key:l.id,label:l.name,definition:l,source:l};return a.setDraft(o,s.key,[...u,m]),{kind:"item",module:o,group:t,docKey:s.key,itemKey:l.id}}}}const qi=[["isPrimaryKey","PK","Primary key"],["isForeignKey","FK","Foreign key"],["isRequired","Req","Required"]];function Vi({row:t,module:i,docKey:n,index:a,preset:d,session:s,readOnly:o,editButton:u,onReveal:c}){var k;const{t:l}=h.useNiceTranslation(),r=me(i,n),p=r?ne(i,r):void 0,m=Array.isArray(p)?p[a]:void 0;if(!r||!p||!m)return e.jsx(ie,{icon:"table",title:t.label,children:e.jsx("p",{className:"nice-development-studio__muted",children:l("devStudio.edit.gone","This is no longer in the module.")})});const g=((k=d.entities)==null?void 0:k.fieldsKey)??"fields",f=Array.isArray(m[g])?m[g]:[],v=o(i.key);return e.jsxs(ie,{icon:"table",title:Qe(m)||t.label,subtitle:String(m.name??""),badges:e.jsxs(e.Fragment,{children:[!!m.isAudited&&e.jsx("span",{className:"nice-development-studio__tag",children:l("entityEditor.flag.audited.abbr","Audit")}),!!m.isSoftDeleteEnabled&&e.jsx("span",{className:"nice-development-studio__tag",children:l("entityEditor.flag.softDelete.abbr","Soft-del")})]}),actions:e.jsxs(e.Fragment,{children:[u,!v&&e.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:e.jsx(h.NiceIcon,{name:"trash",size:14}),onClick:()=>{s.setDraft(i.key,r.key,et(p,a,null)),c({kind:"group",module:i.key,group:"entities"})},children:l("devStudio.delete","Delete")})]}),children:[typeof m.description=="string"&&m.description&&e.jsx("p",{children:m.description}),e.jsx(oe,{items:[[l("entityEditor.col.table","Table"),m.tableName],[l("entityEditor.col.fields","Fields"),String(f.length)]]}),f.length>0&&e.jsx("table",{className:"nice-development-studio__table nice-development-studio__preview-fields",children:e.jsx("tbody",{children:f.slice(0,8).map((N,E)=>e.jsxs("tr",{children:[e.jsx("td",{children:String(N.name??"")}),e.jsx("td",{className:"nice-development-studio__muted",children:String(N.dataType??N.type??"")}),e.jsx("td",{children:qi.filter(([M])=>N[M]||M==="isRequired"&&N.required).map(([,M,S])=>e.jsx("span",{className:"nice-development-studio__tag",title:S,children:M},M))})]},E))})}),f.length>8&&e.jsx("span",{className:"nice-development-studio__muted",children:l("devStudio.preview.more","…and {count} more").replace("{count}",String(f.length-8))})]})}function Wi({row:t,module:i,node:n,advanced:a,renderViewPreview:d,editButton:s}){var m,g,f,v;const{t:o}=h.useNiceTranslation(),u=me(i,n.docKey),c=u?pe(i,u).find(k=>k.key===n.itemKey):void 0;if(!c)return e.jsx(ie,{icon:t.icon,title:t.label,children:e.jsx("p",{className:"nice-development-studio__muted",children:o("devStudio.edit.gone","This is no longer in the module.")})});const l=c.source??{},r=c.definition??{},p=n.group==="views"?[["Id",c.key],[o("devStudio.preview.type","Type"),l.viewType??l.type??l.kind],[o("devStudio.preview.entity","Entity"),l.entityName??l.entity],[o("devStudio.preview.columns","Columns"),(m=Te(l.columns))==null?void 0:m.toString()],[o("devStudio.preview.rows","Rows"),(g=Te(r.rows))==null?void 0:g.toString()]]:n.group==="workflows"?[["Id",c.key],[o("devStudio.preview.states","States"),(f=Te(r.states??l.states))==null?void 0:f.toString()],[o("devStudio.preview.transitions","Transitions"),(v=Te(r.transitions??l.transitions))==null?void 0:v.toString()]]:[[o("devStudio.preview.key","Key"),c.key],[o("devStudio.preview.type","Type"),r.kind??void 0]];return e.jsxs(ie,{icon:t.icon,title:c.label||c.key,badges:c.definition===void 0?e.jsx("span",{className:"nice-development-studio__tag",children:o("devStudio.tree.noForm","no designer")}):void 0,actions:s,children:[e.jsx(oe,{items:p}),c.definition===void 0&&e.jsx("p",{className:"nice-development-studio__muted",children:a?o("devStudio.preview.noDesignerAdvanced","There is no designer for this kind of entry yet; edit its source."):o("devStudio.preview.noDesigner","There is no designer for this kind of entry yet.")}),n.group==="views"&&d&&e.jsx("div",{className:"nice-development-studio__preview-view",children:d({module:i.key,item:c,files:i.working})})]})}function Ji({row:t,module:i,docKey:n,advanced:a,editButton:d}){var l;const{t:s}=h.useNiceTranslation(),o=me(i,n);if(!o)return e.jsx(ie,{icon:t.icon,title:t.label,children:e.jsx("p",{className:"nice-development-studio__muted",children:s("devStudio.edit.gone","This is no longer in the module.")})});const u=ne(i,o);let c=null;if(o.model===void 0)c=e.jsxs("p",{className:"nice-development-studio__error",role:"alert",children:[a?s("devStudio.doc.unreadable","This file could not be read as its kind; edit its source."):s("devStudio.preview.unreadable","This file does not read; saving leaves it as it is. Fix it in the advanced mode.")," ",o.error]});else if(o.kind.editor==="i18n"){const r=u??{},p=Math.max(0,...Object.values(r).map(m=>Object.keys(m??{}).length));c=e.jsx(oe,{items:Object.entries(r).map(([m,g])=>{const f=Object.keys(g??{}).length;return[m,f<p?s("devStudio.preview.keysMissing","{count} keys, {missing} missing").replace("{count}",String(f)).replace("{missing}",String(p-f)):s("devStudio.preview.keys","{count} keys").replace("{count}",String(f))]})})}else if(o.kind.editor==="permissions"){const r=u??{permissions:[],groups:[]};c=e.jsx(oe,{items:[[s("devStudio.permissions.codes","Permissions"),String(r.permissions.length)],[s("devStudio.permissions.groups","Groups"),String(r.groups.length)]]})}else if(o.kind.editor==="seeds"){const r=u??{seeds:{}};c=e.jsx(oe,{items:Object.entries(r.seeds??{}).map(([p,m])=>[p,s("devStudio.preview.rowsCount","{count} rows").replace("{count}",String(m.length))])})}else o.kind.editor==="hooks"?c=e.jsx(oe,{items:[[s("devStudio.preview.bindings","Bindings"),(l=Te(u))==null?void 0:l.toString()]]}):o.kind.editor==="script"&&(c=e.jsx(oe,{items:[[s("devStudio.preview.lines","Lines"),String(String(u??"").split(`
|
|
6
|
+
`).length)]]}));return e.jsx(ie,{icon:t.icon,title:t.label,subtitle:o.paths.join(", "),actions:d,children:c})}function Gi({tree:t,selected:i,expanded:n,onExpandedChange:a,onSelect:d,loadModule:s,newItems:o,actions:u,onRefresh:c,tutorialButton:l,emptyText:r,minWidth:p}){const{t:m}=h.useNiceTranslation(),g=x.useMemo(()=>[{field:"label",header:m("devStudio.explorer.name","Name"),render:(v,k)=>e.jsxs("span",{className:"nice-development-studio__tree-name",style:{maxWidth:`calc(100% - ${(k.depth??0)*20+28}px)`},children:[e.jsx(h.NiceIcon,{name:k.icon,size:14}),e.jsx("span",{className:`nice-development-studio__tree-label${k.missing?" nice-development-studio__missing":""}`,title:k.label,children:k.label}),k.dirty&&e.jsx("span",{className:"nice-development-studio__dot",title:m("devStudio.explorer.unsaved","Unsaved changes"),children:e.jsx(h.NiceIcon,{name:"circle",size:8})}),!!k.issues&&e.jsx("span",{className:"nice-development-studio__badge",title:m("devStudio.explorer.problems","Problems"),children:k.issues}),k.readOnly&&e.jsx("span",{title:m("devStudio.explorer.readOnly","Read-only"),children:e.jsx(h.NiceIcon,{name:"lock",size:12})}),k.noForm&&e.jsx("span",{className:"nice-development-studio__tag",children:m("devStudio.tree.noForm","no designer")}),k.shadowedBy&&e.jsx("span",{className:"nice-development-studio__tag",title:k.shadowedBy,children:m("devStudio.explorer.shadowed","shadowed")}),k.missing&&e.jsx("span",{className:"nice-development-studio__tag",children:m("devStudio.explorer.missing","missing")})]})},{field:"info",header:"",width:56,align:"right"}],[m]),f=e.jsxs("div",{className:"nice-development-studio__tree-actions",children:[o.length>0&&e.jsx(h.NiceMenu,{variant:"ghost",size:"sm",items:[{id:"new",label:m("devStudio.tree.new","New"),icon:e.jsx(h.NiceIcon,{name:"plus",size:14}),children:o}],"data-testid":"studio-new-menu"}),e.jsx(h.NiceButton,{size:"sm",variant:"ghost",ariaLabel:m("devStudio.refresh","Refresh"),onClick:c,children:e.jsx(h.NiceIcon,{name:"refresh",size:14})}),u==null?void 0:u.map(v=>e.jsx(h.NiceButton,{size:"sm",variant:"ghost",disabled:v.disabled,leftIcon:v.icon?e.jsx(h.NiceIcon,{name:v.icon,size:14}):void 0,onClick:v.onSelect,children:v.label},v.key)),l&&e.jsx("span",{className:"nice-development-studio__spacer"}),l]});return e.jsx("div",{className:"nice-development-studio__tree","data-tour":"devstudio-explorer",style:{minWidth:p},children:e.jsx(h.NiceTreeGrid,{data:t.rows,nested:!0,keyField:"id",childrenField:"children",columns:g,sortable:!1,compact:!0,searchable:!0,searchFields:["label","search"],searchPlaceholder:m("devStudio.tree.search","Search modules, entities and views"),toolbar:f,toolbarActions:["collapseAll"],expandedKeys:n,onExpandedChange:a,hasChildren:v=>v.node.kind==="module"&&!v.children,loadChildren:async v=>(v.node.kind==="module"&&await s(v.node.module),[]),onRowClick:d,rowClassName:v=>v.id===i?"nice-development-studio__tree-row--selected":void 0,emptyText:r,"aria-label":m("devStudio.explorer.modules","Modules"),"data-testid":"studio-tree"})})}const Ui=[{target:".nice-development-studio",titleKey:"tutorial.devStudio.intro.title",title:"Development studio",contentKey:"tutorial.devStudio.intro.content",content:"Design whole modules: their settings, entities, views, workflows, translations, permissions, data sources and seed data. Saving writes back only what changed.",placement:"auto"},{target:'[data-tour="devstudio-explorer"]',titleKey:"tutorial.devStudio.explorer.title",title:"Projects, packages and modules",contentKey:"tutorial.devStudio.explorer.content",content:"Browse projects, their packages and modules. Open a module to see its entities, views, translations and the rest; under Templates are the module sets installed together.",placement:"right"},{target:'[data-testid="studio-preview"]',titleKey:"tutorial.devStudio.preview.title",title:"A short preview",contentKey:"tutorial.devStudio.preview.content",content:"Pick a row in the tree to see a short preview of it here.",placement:"left"},{target:'[data-tour="devstudio-edit"]',titleKey:"tutorial.devStudio.edit.title",title:"Edit on the whole screen",contentKey:"tutorial.devStudio.edit.content",content:"Edit opens the form of what you picked on the whole studio. Back, or a step of the trail, brings you back to the tree.",placement:"bottom"},{target:'[data-tour="devstudio-save"]',titleKey:"tutorial.devStudio.save.title",title:"Validate and save",contentKey:"tutorial.devStudio.save.content",content:"Check the module, review the changed files and save them — only the bytes you changed are written.",placement:"bottom"}],Hi=["en","pl","de","fr","es","uk"],Yi=x.forwardRef(function(i,n){var ot,at;const{provider:a,preset:d,defaultModule:s,defaultExplorerTab:o="modules",displayMode:u="standard",actions:c,onModuleOpen:l,onSaved:r,onError:p,reviewBeforeSave:m=!0,scriptRunner:g,renderViewPreview:f,modulePanels:v,readOnly:k=!1,height:N=720,explorerWidth:E=320,previewWidth:M=260,tutorial:S,className:y,style:w,id:_,testId:O,"data-testid":B}=i,{t:P}=h.useNiceTranslation(),ee=x.useRef(null);x.useImperativeHandle(n,()=>ee.current);const Z=u==="advanced",Y=x.useMemo(()=>typeof d=="function"?d(P):d??D.nativeStudioPreset,[d,P]),J=x.useMemo(()=>Y.locales??Hi,[Y]),C=pi(a,Y,{locales:J,onError:p}),{openModule:$}=C,[R,L]=x.useState(""),[H,W]=x.useState([]),[z,G]=x.useState(null),[re,T]=x.useState(null),[j,I]=x.useState(null),F=x.useCallback(b=>{var K;return(K=C.modulesByWs[b.workspaceId])==null?void 0:K.find(q=>q.id===b.id)},[C.modulesByWs]),A=b=>{var K;return((K=F(b))==null?void 0:K.label)??b.id},V=x.useMemo(()=>{const b={};for(const[K,q]of Object.entries(C.modules))b[K]=[...St(q,Y),...C.serverIssues[K]??[]];return b},[C.modules,C.serverIssues,Y]),Q=x.useCallback(b=>V[X(b)]??[],[V]),U=x.useMemo(()=>Object.fromEntries(Object.entries(V).map(([b,K])=>[b,K.filter(q=>q.severity==="error").length])),[V]),le=x.useCallback(b=>{var q;if(k)return!0;if(!b)return!1;const K=C.workspaces.find(fe=>fe.id===b.workspaceId);return!!(K!=null&&K.readOnly)||!!((q=F(b))!=null&&q.readOnly)},[k,C.workspaces,F]),te=x.useMemo(()=>gi({workspaces:C.workspaces,modulesByWs:C.modulesByWs,packagesByWs:C.packagesByWs,templates:C.templates,modules:C.modules,issueCounts:U,panels:v?b=>v({module:b.key,files:b.working,dirty:b.dirty}):void 0,advanced:Z,t:P}),[C.workspaces,C.modulesByWs,C.packagesByWs,C.templates,C.modules,U,v,Z,P]),ae=x.useRef(!1);x.useEffect(()=>{if(!ae.current&&C.workspaces.length>0){ae.current=!0;const b=C.workspaces.map(K=>`w:${K.id}`);o==="templates"&&(b.push(Me),L(Me)),W(K=>[...new Set([...K,...b])])}},[C.workspaces,o]);const ce=x.useCallback(b=>{const K=ht(te,b).map(q=>q.id);W(q=>[...new Set([...q,...K])]),L(b)},[te]),de=x.useCallback(b=>{G(null);const K=$e(b);K&&!C.modules[X(K)]&&$(K),T(b)},[C.modules,$]);x.useEffect(()=>{if(!re)return;const b=qe(te,re);if(b){ce(b),T(null);return}const K=$e(re);if(K&&C.modules[X(K)]){const q=qe(te,{kind:"module",module:K});q&&ce(q),T(null)}},[re,te,ce,C.modules]);const Ne=x.useCallback(b=>{L(b.id);const K=$e(b.node);K&&!C.modules[X(K)]&&$(K),b.node.kind==="module"&&(l==null||l(b.node.module))},[C.modules,$,l]),Et=x.useCallback(b=>{const K=te.byId.get(b);K&&(Ne(K),ce(b))},[te,Ne,ce]),tt=x.useRef(!1);x.useEffect(()=>{s&&!tt.current&&C.modulesByWs[s.workspaceId]&&(tt.current=!0,$(s).then(()=>l==null?void 0:l(s)),T({kind:"module",module:s}))},[s,C.modulesByWs,$,l]);const ke=te.byId.get(R),ue=z?"module"in z?z.module:void 0:ke?$e(ke.node):void 0,Ke=x.useCallback(async b=>{const K=C.modules[X(b)];if(!(K!=null&&K.dirty)||le(b))return;if(m){I({kind:"review",module:b});return}const q=await C.save(b);q&&!q.ok?I({kind:"review",module:b,conflict:q}):q!=null&&q.ok&&(r==null||r(b,q))},[C,le,m,r]),it=x.useRef(()=>{});it.current=()=>{ue&&Ke(ue)},x.useEffect(()=>{const b=ee.current;if(!b)return;const K=q=>{(q.ctrlKey||q.metaKey)&&!q.altKey&&q.key.toLowerCase()==="s"&&(q.preventDefault(),it.current())};return b.addEventListener("keydown",K),()=>b.removeEventListener("keydown",K)},[]);const $t=()=>{const b=z?ft(z):void 0;b?de(b):G(null)},Mt=x.useMemo(()=>{if(!z)return[];const b=ft(z),K=b?qe(te,b):void 0,q=K?ht(te,K):[],fe=z.kind==="manifest"?P("devStudio.edit.settings","Settings"):z.kind==="problems"?P("devStudio.overview.problems","Problems"):z.kind==="history"?P("devStudio.overview.history","History"):z.kind==="template"&&!z.templateId?P("devStudio.template.new","New template"):void 0,ve=q.map(dt=>({label:dt.label,onClick:()=>{G(null),ce(dt.id)}}));return fe?ve.push({label:fe}):ve.length>0&&(ve[ve.length-1]={label:ve[ve.length-1].label}),ve},[z,te,ce,P]),nt=!!(a!=null&&a.createModule)&&!!Y.generateModule,Kt=!!(a!=null&&a.createModule)&&!!Y.duplicateModule,_e=C.workspaces.filter(b=>!b.readOnly).map(b=>({id:b.id,label:b.label})),se=ke==null?void 0:ke.node,Oe=se&&"workspaceId"in se?se.workspaceId:se&&"module"in se?se.module.workspaceId:void 0,Ot=(se==null?void 0:se.kind)==="package"?se.packageId:se&&"module"in se?(ot=F(se.module))==null?void 0:ot.packageId:void 0,Ie=_e.some(b=>b.id===Oe)?Oe:(at=_e[0])==null?void 0:at.id,Ft=k?[]:[...nt&&Ie?[{id:"module",label:P("devStudio.tree.newModule","Module…"),icon:e.jsx(h.NiceIcon,{name:"box",size:14}),onClick:()=>I({kind:"wizard",prefill:{workspaceId:Ie,packageId:Ie===Oe?Ot:void 0}})}]:[],...a!=null&&a.savePackage&&Ie?[{id:"package",label:P("devStudio.tree.newPackage","Package…"),icon:e.jsx(h.NiceIcon,{name:"archive",size:14}),onClick:()=>I({kind:"package",workspaceId:Ie})}]:[],...a!=null&&a.saveTemplate&&C.templates?[{id:"template",label:P("devStudio.tree.newTemplate","Template"),icon:e.jsx(h.NiceIcon,{name:"layers",size:14}),onClick:()=>G({kind:"template",templateId:null})}]:[]],Bt=(b,K)=>{I(b==="delete"?{kind:"delete",module:K}:b==="duplicate"?{kind:"duplicate",module:K}:{kind:"templates",module:K})},st=S?e.jsx(h.NiceTutorialButton,{steps:h.resolveTutorial(S,Ui)}):void 0,Ce=ue?C.modules[X(ue)]:void 0,Fe=ue?Q(ue):[],Be=C.logs[C.logs.length-1],zt=e.jsxs("div",{className:"nice-development-studio__statusbar",role:"status",children:[ue&&e.jsxs(e.Fragment,{children:[e.jsx("span",{children:A(ue)}),e.jsx("span",{children:Ce!=null&&Ce.dirty?P("devStudio.status.changed","{count} changed files").replace("{count}",String(Ce.changes.length)):P("devStudio.status.saved","Saved")}),e.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:e.jsx(h.NiceIcon,{name:Fe.length===0?"check":"warning",size:12}),onClick:()=>G({kind:"problems",module:ue}),children:Fe.length===0?P("devStudio.status.valid","No problems"):P("devStudio.status.problems","{count} problems").replace("{count}",String(Fe.length))})]}),e.jsx("span",{className:"nice-development-studio__spacer"}),C.busy?e.jsx("span",{children:P("devStudio.loading","Loading…")}):Be&&e.jsx("span",{className:`nice-development-studio__status-message nice-development-studio__status-message--${Be.level}`,children:Be.message})]}),ze=(j==null?void 0:j.kind)==="review"?C.modules[X(j.module)]:void 0,Dt=`nice-development-studio${y?` ${y}`:""}`,Pt=a?P("devStudio.preview.empty","Pick a module, an entity or a view in the tree."):P("devStudio.noProvider","Connect a provider to browse modules.");return e.jsxs("div",{ref:ee,id:_,className:Dt,style:{height:N,...w},"data-testid":B??O,children:[e.jsx(h.NiceAppShell,{className:"nice-development-studio__shell",height:"100%",rightSidebar:z?void 0:e.jsx(zi,{row:ke,tree:te,session:C,preset:Y,provider:a,readOnly:le,advanced:Z,issues:Q,canCreateModule:nt,canDuplicateModule:Kt,renderViewPreview:f,emptyText:Pt,onSelect:Et,onEdit:G,onReveal:de,onSave:b=>void Ke(b),onNewModule:b=>I({kind:"wizard",prefill:b}),onNewPackage:b=>I({kind:"package",workspaceId:b}),onNewTemplate:()=>G({kind:"template",templateId:null}),onModuleAction:Bt}),rightSidebarWidth:M,statusBar:zt,bottomPanel:Z?e.jsx("div",{"data-tour":"devstudio-output",className:"nice-development-studio__output",children:e.jsx(h.NiceLogConsole,{title:P("devStudio.output","Output"),entries:C.logs,onClear:C.clearLogs,maxHeight:"100%"})}):void 0,bottomPanelHeight:Z?140:void 0,children:z?e.jsx($i,{screen:z,crumbs:Mt,session:C,preset:Y,provider:a,locales:J,readOnly:le,advanced:Z,issues:Q,scriptRunner:g,renderViewPreview:f,modulePanels:v,tutorialButton:st,onBack:$t,onSave:b=>void Ke(b),onReveal:de,onScreen:G,onNewModule:b=>I({kind:"wizard",prefill:b})}):e.jsx(Gi,{tree:te,selected:R,expanded:H,onExpandedChange:W,onSelect:Ne,loadModule:async b=>{await $(b)},newItems:Ft,actions:c,onRefresh:()=>void C.refresh(),tutorialButton:st,minWidth:E,emptyText:a?P("devStudio.explorer.empty","No modules."):P("devStudio.noProvider","Connect a provider to browse modules.")})}),(j==null?void 0:j.kind)==="wizard"&&e.jsx(ri,{open:!0,onClose:()=>I(null),session:C,preset:Y,locales:J,prefill:j.prefill,onCreated:b=>{l==null||l(b),de({kind:"module",module:b})}}),(j==null?void 0:j.kind)==="review"&&ze&&e.jsx(li,{open:!0,moduleLabel:A(j.module),changes:ze.changes,original:b=>{var K;return((K=ze.files.find(q=>q.path===b))==null?void 0:K.text)??""},conflict:j.conflict,onClose:()=>I(null),onSave:async()=>{const b=await C.save(j.module);b!=null&&b.ok?(I(null),r==null||r(j.module,b)):b&&I({...j,conflict:b})},onOverwrite:async()=>{const b=await C.save(j.module,{force:!0});b!=null&&b.ok&&(I(null),r==null||r(j.module,b))},onReload:async()=>{await C.reload(j.module),I(null)}}),(j==null?void 0:j.kind)==="delete"&&e.jsx(h.NiceConfirmDialog,{visible:!0,variant:"warning",header:P("devStudio.delete.title","Delete module"),message:P("devStudio.delete.message","Delete {module} and all its files?").replace("{module}",A(j.module)),acceptLabel:P("devStudio.delete","Delete"),rejectLabel:P("devStudio.cancel","Cancel"),onReject:()=>I(null),onAccept:async()=>{const b=j.module;I(null),await C.deleteModule(b)&&(G(null),L(`w:${b.workspaceId}`))}}),(j==null?void 0:j.kind)==="duplicate"&&e.jsx(ut,{open:!0,title:P("devStudio.duplicate.title","Duplicate {module}").replace("{module}",A(j.module)),workspaces:_e,workspaceId:_e.some(b=>b.id===j.module.workspaceId)?j.module.workspaceId:void 0,idLabel:P("devStudio.duplicate.id","New module id"),initialId:`${j.module.id}Copy`,onClose:()=>I(null),onSubmit:async b=>{var fe;const K=j.module;I(null);const q=await C.duplicateModule(K,{workspaceId:b.workspaceId,id:b.id,packageId:(fe=F(K))==null?void 0:fe.packageId});q&&de({kind:"module",module:{workspaceId:q.workspaceId,id:q.id}})}}),(j==null?void 0:j.kind)==="package"&&e.jsx(ut,{open:!0,title:P("devStudio.package.new","New package"),workspaces:_e,workspaceId:j.workspaceId,idLabel:P("devStudio.package.id","Id"),withLabel:!0,onClose:()=>I(null),onSubmit:async b=>{I(null);const K=await C.savePackage({id:b.id,workspaceId:b.workspaceId,label:b.label});K&&de({kind:"package",workspaceId:K.workspaceId,packageId:K.id})}}),(j==null?void 0:j.kind)==="templates"&&C.templates&&e.jsx(ci,{open:!0,moduleId:j.module.id,templates:C.templates,onClose:()=>I(null),onApply:async b=>{I(null);for(const K of b)await C.saveTemplate(K,K.id)}})]})});exports.arrayFileKind=D.arrayFileKind;exports.buildDocuments=D.buildDocuments;exports.createMemoryStudioProvider=D.createMemoryStudioProvider;exports.defineManifestSection=D.defineManifestSection;exports.deriveDefaultRbac=D.deriveDefaultRbac;exports.detectJsonTextFormat=D.detectJsonTextFormat;exports.encodeDocument=D.encodeDocument;exports.endsWithAny=D.endsWithAny;exports.entitiesToSchemas=D.entitiesToSchemas;exports.fileName=D.fileName;exports.fitManifestSection=D.fitManifestSection;exports.i18nFileKind=D.i18nFileKind;exports.itemsFileKind=D.itemsFileKind;exports.jsonFallbackKind=D.jsonFallbackKind;exports.jsonFileKind=D.jsonFileKind;exports.jsonValueFitsSchema=D.jsonValueFitsSchema;exports.jsonValuesEqual=D.jsonValuesEqual;exports.keepTextFormat=D.keepTextFormat;exports.manifestSectionKeys=D.manifestSectionKeys;exports.modulePrefix=D.modulePrefix;exports.nativeDataSourcesKind=D.nativeDataSourcesKind;exports.nativeEntitiesKind=D.nativeEntitiesKind;exports.nativeFileKinds=D.nativeFileKinds;exports.nativeHooksKind=D.nativeHooksKind;exports.nativeI18nKind=D.nativeI18nKind;exports.nativeManifestKind=D.nativeManifestKind;exports.nativeRbacKind=D.nativeRbacKind;exports.nativeStudioPreset=D.nativeStudioPreset;exports.nativeViewsKind=D.nativeViewsKind;exports.nativeWorkflowsKind=D.nativeWorkflowsKind;exports.objectFileKind=D.objectFileKind;exports.parseJsonText=D.parseJsonText;exports.patchJsonText=D.patchJsonText;exports.patchJsonTextDetailed=D.patchJsonTextDetailed;exports.readTranslations=D.readTranslations;exports.resolveFileKind=D.resolveFileKind;exports.safeJson=D.safeJson;exports.slugifyModuleId=D.slugifyModuleId;exports.stringifyJsonText=D.stringifyJsonText;exports.textFallbackKind=D.textFallbackKind;exports.writeTranslations=D.writeTranslations;exports.NiceArrayField=Ue;exports.NiceDevelopmentStudio=Yi;exports.NiceEntityEditor=bt;exports.NiceEntityForm=He;exports.NiceI18nEditor=Xe;exports.NiceSchemaForm=we;exports.aiFormConfigToFormFields=Vt;exports.aiFormFieldType=gt;exports.formBuilderSchemaToNiceFormItems=Rt;exports.formFieldsToFormItems=Je;exports.formSchemaToJsonSchema=Ut;exports.jsonSchemaToFormItems=We;exports.schemaToFormItems=At;exports.validateAgainstJsonSchema=Ge;exports.validateFormSchema=Lt;
|