@nice2dev/ui-forms 1.4.5 → 1.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +7 -5
- package/dist/index.d.ts +150 -7
- package/dist/index.mjs +3048 -2256
- package/dist/studio.cjs +21 -8
- package/dist/studio.d.ts +144 -7
- package/dist/studio.mjs +814 -605
- package/dist/ui-forms.css +1 -1
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),
|
|
2
|
-
`).length)),onChange:m=>{const r=m.target.value;d(r);const c=r.trim();if(c===""){
|
|
3
|
-
`).length)),onChange:A=>{const te=A.target.value;V(te);try{const X=JSON.parse(te);Y(null),x(X)}catch(X){Y(X instanceof Error?X.message:g("schemaForm.invalidJson","Invalid JSON"))}}}),G&&t.jsx("div",{className:"nice-schema-form__json-error",children:G})]}):t.jsx(h.NiceForm,{items:H,data:k,onFieldChange:O,columns:c,labelPosition:p,readOnly:b}),f&&$.length>0&&t.jsx("ul",{className:"nice-schema-form__errors",role:"alert",children:$.map((A,te)=>t.jsx("li",{className:"nice-schema-form__error",children:A.message},`${A.field}-${te}`))})]})}),Ve="__eeFid",ui={},_t={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"]},It={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 We({title:e,help:i}){return t.jsxs("span",{className:"nice-entity-editor__field-label",children:[e,i?t.jsx(h.NiceTooltip,{content:i,children:t.jsx("span",{className:"nice-entity-editor__help",role:"img","aria-label":i,children:t.jsx(h.NiceIcon,{name:"info",size:14})})}):null]})}function mi({schema:e,value:i,onChange:n,readOnly:o}){const a=e.properties??{};return t.jsx("div",{className:"nice-entity-editor__field-form",children:Object.entries(a).map(([s,d])=>{const u=i[s],l=d.description,m=d.title??s;if(d.type==="boolean")return t.jsx("div",{className:"nice-entity-editor__field-row nice-entity-editor__field-row--check",children:t.jsx(h.NiceCheckbox,{label:t.jsx(We,{title:m,help:l}),checked:!!u,onChange:c=>n(s,c),disabled:o})},s);if(Array.isArray(d.enum)&&d.enum.length>0)return t.jsxs("div",{className:"nice-entity-editor__field-row",children:[t.jsx(We,{title:m,help:l}),t.jsx(h.NiceSelect,{options:d.enum.map(c=>({label:String(c),value:String(c)})),value:u==null?"":String(u),onChange:c=>n(s,c),clearable:!0,disabled:o})]},s);const r=d.type==="integer"||d.type==="number";return t.jsxs("div",{className:"nice-entity-editor__field-row",children:[t.jsx(We,{title:m,help:l}),t.jsx(h.NiceTextInput,{value:u==null?"":String(u),onChange:c=>n(s,r?c===""?void 0:Number(c):c),disabled:o})]},s)})})}function pi({fields:e,onChange:i,fieldSchema:n,readOnly:o}){const{t:a}=h.useNiceTranslation(),[s,d]=j.useState(null),u=j.useMemo(()=>e.map((c,p)=>({...c,[Ve]:String(p)})),[e]),l=j.useMemo(()=>[{field:"name",header:a("entityEditor.field.name","Name"),sortable:!0,render:c=>t.jsx("span",{className:"nice-entity-editor__name",children:String(c??"")})},{field:"dataType",header:a("entityEditor.field.type","Type"),sortable:!0,render:c=>t.jsx(h.NiceBadge,{variant:"secondary",size:"sm",outline:!0,children:String(c??"—")})},{field:"__flags",header:a("entityEditor.field.flags","Constraints"),headerTooltip:a("entityEditor.field.flags.help","Key / required / unique / indexed constraints on this field"),render:(c,p)=>{const b=[[!!(p!=null&&p.isPrimaryKey),"PK",a("entityEditor.flag.pk","Primary key"),"info"],[!!(p!=null&&p.isForeignKey),"FK",a("entityEditor.flag.fk","Foreign key"),"info"],[!!(p!=null&&p.isRequired),"Req",a("entityEditor.flag.required","Required (NOT NULL)"),"warning"],[!!(p!=null&&p.isUnique),"Uniq",a("entityEditor.flag.unique","Unique"),"secondary"],[!!(p!=null&&p.isIndexed),"Idx",a("entityEditor.flag.indexed","Indexed"),"secondary"]];return t.jsx("span",{className:"nice-entity-editor__flags",children:b.filter(([f])=>f).map(([,f,v,y])=>t.jsx(h.NiceTooltip,{content:v,children:t.jsx(h.NiceBadge,{variant:y,size:"sm",children:f})},f))})}}],[]),m=(c,p,b)=>{i(e.map((f,v)=>v===c?{...f,[p]:b}:f))},r=()=>{const c=[...e,{name:`field${e.length+1}`,dataType:"string"}];i(c),d(c.length-1)};if(s!=null&&e[s]){const c=e[s];return t.jsxs("div",{className:"nice-entity-editor__field-detail",children:[t.jsxs("header",{className:"nice-entity-editor__edit-header",children:[t.jsx(h.NiceTooltip,{content:a("entityEditor.field.backHint","Back to the field list"),children:t.jsx(h.NiceButton,{variant:"ghost",size:"sm",leftIcon:t.jsx(h.NiceIcon,{name:"arrow-left",size:14}),onClick:()=>d(null),children:a("entityEditor.field.back","Fields")})}),t.jsx("span",{className:"nice-entity-editor__breadcrumb-sep",children:"/"}),t.jsx("span",{className:"nice-entity-editor__edit-title",children:String(c.name??a("entityEditor.field.untitled","New field"))})]}),t.jsx(mi,{schema:n,value:c,onChange:(p,b)=>m(s,p,b),readOnly:o}),t.jsx("div",{className:"nice-entity-editor__field-detail-actions",children:t.jsx(h.NiceButton,{variant:"primary",size:"sm",onClick:()=>d(null),children:a("entityEditor.field.done","Done")})})]})}return t.jsx(h.NiceDataGrid,{data:u,keyField:Ve,columns:l,searchable:!0,searchPlaceholder:a("entityEditor.field.search","Search fields…"),emptyText:a("entityEditor.field.empty","No fields yet. Add one to define this entity."),onRowClick:c=>d(Number(c[Ve])),onRowDelete:o?void 0:c=>i(e.filter((p,b)=>b!==Number(c))),toolbar:o?void 0:t.jsx(h.NiceButton,{variant:"primary",size:"sm",leftIcon:t.jsx(h.NiceIcon,{name:"plus",size:14}),onClick:r,children:a("entityEditor.field.add","Add field")}),compact:!0,striped:!0})}const it=j.forwardRef(function(i,n){const{value:o,defaultValue:a,onChange:s,entityMetaSchema:d=_t,fieldSchema:u=It,fieldsKey:l="fields",validationsKey:m="validations",activeTab:r,defaultActiveTab:c="general",onActiveTabChange:p,extraTabs:b,readOnly:f=!1,className:v,style:y,id:S,"data-testid":N}=i,{t:C}=h.useNiceTranslation(),[w,g]=h.useControllableState({value:o,defaultValue:a,fallbackValue:ui,onChange:s,componentName:"NiceEntityForm"}),[k,x]=h.useControllableState({value:r,defaultValue:c,fallbackValue:"general",onChange:p,componentName:"NiceEntityForm"}),F=j.useMemo(()=>{const H=w[l];return Array.isArray(H)?H:[]},[w,l]),L=j.useMemo(()=>{const H=O=>{const P=O.toLowerCase();return/(int|long|decimal|double|float|number|money)/.test(P)?"number":/bool/.test(P)?"boolean":/date|time/.test(P)?"date":"string"},$=[];for(const O of F){const P=String(O.name??"");P&&$.push({field:P,label:String(O.displayName??P),type:H(String(O.dataType??"string"))})}return $},[F]),K=j.useMemo(()=>{const H=w[m];return Array.isArray(H)?H:[]},[w,m]),V=H=>{g({...w,...H})},G=[{id:"general",label:C("entityEditor.tab.general","General"),content:t.jsx(_e,{schema:d,value:w,onChange:H=>V(H),columns:2,readOnly:f,liveValidation:!0})},{id:"fields",label:C("entityEditor.tab.fields","Fields"),badge:F.length||void 0,content:t.jsx(pi,{fields:F,onChange:H=>V({[l]:H}),fieldSchema:u,readOnly:f})},{id:"validation",label:C("entityEditor.tab.validation","Validation"),badge:K.length||void 0,content:t.jsx(h.NiceValidationBuilder,{fields:L,value:K,onChange:H=>V({[m]:H})})},...b??[]],Y="nice-entity-form"+(v?` ${v}`:"");return t.jsx("div",{ref:n,id:S,className:Y,style:y,"data-testid":N,children:t.jsx(h.NiceTabs,{tabs:G,activeTab:k,onChange:x,variant:"enclosed"})})}),Je="__eeRid",hi=[{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"}],Tt=j.forwardRef(function(i,n){const{value:o,defaultValue:a,onChange:s,entityMetaSchema:d=_t,fieldSchema:u=It,fieldsKey:l="fields",validationsKey:m="validations",nameKey:r="name",renderErPreview:c,readOnly:p=!1,tutorial:b,className:f,style:v,id:y,"data-testid":S}=i,{t:N}=h.useNiceTranslation(),[C,w]=h.useControllableState({value:o,defaultValue:a,fallbackValue:[],onChange:s,componentName:"NiceEntityEditor"}),[g,k]=j.useState("list"),[x,F]=j.useState(0),[L,K]=j.useState("general"),V=Math.min(x,Math.max(0,C.length-1)),G=C[V],Y=g==="edit"&&G!=null,H=j.useMemo(()=>C.map((D,Z)=>({...D,[Je]:String(Z)})),[C]),$=D=>{F(D),K("general"),k("edit")},O=()=>{const D=[...C,{[r]:`Entity${C.length+1}`,[l]:[]}];w(D),F(D.length-1),K("general"),k("edit")},P=D=>{w(C.filter((Z,re)=>re!==D)),F(Z=>Z>=D?Math.max(0,Z-1):Z)},A=j.useMemo(()=>[{field:r,header:N("entityEditor.col.name","Name"),sortable:!0,render:D=>t.jsx("span",{className:"nice-entity-editor__name",children:String(D??"")})},{field:"displayName",header:N("entityEditor.col.displayName","Display name"),sortable:!0,render:D=>t.jsx("span",{className:"nice-entity-editor__muted",children:String(D??"—")})},{field:"tableName",header:N("entityEditor.col.table","Table"),sortable:!0,render:D=>t.jsx("span",{className:"nice-entity-editor__muted",children:String(D??"—")})},{field:l,header:N("entityEditor.col.fields","Fields"),align:"center",headerTooltip:N("entityEditor.col.fields.help","Number of fields defined on this entity"),render:D=>t.jsx(h.NiceBadge,{variant:"secondary",size:"sm",children:Array.isArray(D)?D.length:0})},{field:"__flags",header:N("entityEditor.col.flags","Flags"),render:(D,Z)=>t.jsxs("span",{className:"nice-entity-editor__flags",children:[Z!=null&&Z.isAudited?t.jsx(h.NiceTooltip,{content:N("entityEditor.flag.audited","Audited — tracks who changed each record and when"),children:t.jsx(h.NiceBadge,{variant:"info",size:"sm",outline:!0,children:N("entityEditor.flag.audited.abbr","Audit")})}):null,Z!=null&&Z.isSoftDeleteEnabled?t.jsx(h.NiceTooltip,{content:N("entityEditor.flag.softDelete","Soft delete — rows are flagged deleted, never physically removed"),children:t.jsx(h.NiceBadge,{variant:"secondary",size:"sm",outline:!0,children:N("entityEditor.flag.softDelete.abbr","Soft-del")})}):null]})}],[r,l]),te=c?[{id:"er",label:N("entityEditor.tab.er","ER diagram"),content:t.jsx("div",{className:"nice-entity-editor__er",children:c(C)})}]:void 0,X="nice-entity-editor"+(f?` ${f}`:"");return t.jsxs("div",{ref:n,id:y,className:X,style:v,"data-testid":S,children:[b&&t.jsx("div",{className:"nice-entity-editor__tutorial",children:t.jsx(h.NiceTutorialButton,{steps:h.resolveTutorial(b,hi)})}),Y?t.jsxs("div",{className:"nice-entity-editor__edit",children:[t.jsxs("header",{className:"nice-entity-editor__edit-header",children:[t.jsx(h.NiceTooltip,{content:N("entityEditor.backHint","Back to the entity list"),children:t.jsx(h.NiceButton,{variant:"ghost",size:"sm",leftIcon:t.jsx(h.NiceIcon,{name:"arrow-left",size:14}),onClick:()=>k("list"),children:N("entityEditor.back","Entities")})}),t.jsx("span",{className:"nice-entity-editor__breadcrumb-sep",children:"/"}),t.jsx("span",{className:"nice-entity-editor__edit-title",children:String((G==null?void 0:G[r])??N("entityEditor.untitled","Untitled entity"))}),!p&&t.jsx(h.NiceTooltip,{content:N("entityEditor.deleteHint","Delete this entity"),children:t.jsx(h.NiceButton,{variant:"ghost",size:"sm",leftIcon:t.jsx(h.NiceIcon,{name:"trash",size:14}),onClick:()=>{P(V),k("list")},children:N("entityEditor.delete","Delete")})})]}),t.jsx(it,{value:G,onChange:D=>w(C.map((Z,re)=>re===V?D:Z)),entityMetaSchema:d,fieldSchema:u,fieldsKey:l,validationsKey:m,activeTab:L,onActiveTabChange:K,extraTabs:te,readOnly:p})]}):t.jsx("div",{className:"nice-entity-editor__list-view",children:t.jsx(h.NiceDataGrid,{data:H,keyField:Je,columns:A,searchable:!0,searchPlaceholder:N("entityEditor.search","Search entities…"),emptyText:N("entityEditor.empty","No entities yet. Create one to get started."),onRowClick:D=>$(Number(D[Je])),onRowDelete:p?void 0:D=>P(Number(D)),toolbar:p?void 0:t.jsx(h.NiceButton,{variant:"primary",size:"sm",leftIcon:t.jsx(h.NiceIcon,{name:"plus",size:14}),onClick:O,children:N("entityEditor.new","New entity")}),compact:!0,striped:!0})})]})}),fi=4e6;function vi(e,i){const n=e.split(/\r?\n/),o=i.split(/\r?\n/);if(n.length*o.length>fi)return[...n.map(r=>({type:"remove",text:r})),...o.map(r=>({type:"add",text:r}))];const a=n.length,s=o.length,d=Array.from({length:a+1},()=>new Uint32Array(s+1));for(let r=a-1;r>=0;r--)for(let c=s-1;c>=0;c--)d[r][c]=n[r]===o[c]?d[r+1][c+1]+1:Math.max(d[r+1][c],d[r][c+1]);const u=[];let l=0,m=0;for(;l<a&&m<s;)n[l]===o[m]?(u.push({type:"same",text:n[l]}),l++,m++):d[l+1][m]>=d[l][m+1]?u.push({type:"remove",text:n[l++]}):u.push({type:"add",text:o[m++]});for(;l<a;)u.push({type:"remove",text:n[l++]});for(;m<s;)u.push({type:"add",text:o[m++]});return u}function Ct({before:e,after:i,context:n=3}){const{t:o}=h.useNiceTranslation(),a=j.useMemo(()=>{const s=vi(e,i),d=new Set;s.forEach((m,r)=>{if(m.type!=="same")for(let c=Math.max(0,r-n);c<=Math.min(s.length-1,r+n);c++)d.add(c)});const u=[];let l=0;return s.forEach((m,r)=>{d.has(r)?(l>0&&(u.push({type:"gap",count:l}),l=0),u.push(m)):l++}),l>0&&u.length>0&&u.push({type:"gap",count:l}),u},[e,i,n]);return a.length===0?t.jsx("p",{className:"nice-development-studio__muted",children:o("devStudio.diff.none","No changes.")}):t.jsx("pre",{className:"nice-development-studio__diff","aria-label":o("devStudio.diff.label","Changes"),children:a.map((s,d)=>s.type==="gap"?t.jsxs("span",{className:"nice-development-studio__diff-gap",children:[o("devStudio.diff.unchanged","{count} unchanged lines").replace("{count}",String(s.count)),`
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),ke=require("@nice2dev/ui-core"),j=require("react"),h=require("@nice2dev/ui"),$=require("./studio.cjs"),di=require("@nice2dev/ui-diagrams");function ri(e){var o,a;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 e.sections)for(const d of s.fields)d.type==="heading"||d.type==="paragraph"||d.type==="divider"||d.type==="spacer"||d.type==="section"||n.push({field:d.name,label:d.label||d.name,type:i[d.type]||"text",placeholder:d.placeholder,hint:d.helpText,defaultValue:d.defaultValue,required:d.required||((o=d.validations)==null?void 0:o.some(l=>l.type==="required")),disabled:d.disabled,readOnly:d.readonly,group:s.title,options:(a=d.options)==null?void 0:a.map(l=>typeof l=="string"?{label:l,value:l}:{label:l.label,value:l.value})});return n}function kt(e){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:e.name,label:{text:e.label},editorType:i[e.type]||"NiceTextInput",editorOptions:{placeholder:e.placeholder,disabled:e.disabled,readOnly:e.readonly,...e.props},colSpan:Math.ceil((e.colSpan||12)/6),validationRules:(n=e.validations)==null?void 0:n.map(o=>({type:o.type,message:o.message,...o.value!==void 0?{[o.type]:o.value}:{}})),helpText:e.helpText}}function li(e){const i=[];for(const n of e.sections)n.title?i.push({itemType:"group",caption:n.title,colCount:n.columns||2,items:n.fields.map(kt)}):i.push(...n.fields.map(kt));return i}function ci(e){const i=[];e.version||i.push("Missing schema version"),e.id||i.push("Missing form ID"),(!e.sections||e.sections.length===0)&&i.push("Form must have at least one section");const n=new Set;for(const o of e.sections||[])for(const a of o.fields||[])a.id||i.push(`Field missing ID: ${a.name}`),a.name||i.push(`Field missing name: ${a.id}`),n.has(a.name)&&i.push(`Duplicate field name: ${a.name}`),n.add(a.name);return{valid:i.length===0,errors:i}}const ui={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 Tt(e){return ui[String(e??"").toLowerCase()]??"text"}function mi(e){return(Array.isArray(e)?e:e.fields).map((n,o)=>{const a=n.name??n.field??n.id??`field${o+1}`,s=n.validation??{},d=[],l=(u,m)=>{m!==void 0&&d.push({type:u,value:m,...s.message?{message:s.message}:{}})};return l("min",s.min),l("max",s.max),l("minLength",s.minLength),l("maxLength",s.maxLength),l("pattern",s.pattern),{id:n.id??a,name:a,type:Tt(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]}:{},...d.length?{validations:d}:{}}})}const pi={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 hi(e,i){if(i)for(const n of i)switch(n.type){case"minLength":typeof n.value=="number"&&(e.minLength=n.value);break;case"maxLength":typeof n.value=="number"&&(e.maxLength=n.value);break;case"min":typeof n.value=="number"&&(e.minimum=n.value);break;case"max":typeof n.value=="number"&&(e.maximum=n.value);break;case"pattern":typeof n.value=="string"&&(e.pattern=n.value);break;case"email":e.format="email";break;case"url":e.format="uri";break}}function vi(e){if(e.type==="heading"||e.type==="paragraph"||e.type==="divider"||e.type==="spacer")return null;const i=pi[e.type];if(!i)return null;const n={...i};return e.label&&(n.title=e.label),e.helpText&&(n.description=e.helpText),e.defaultValue!==void 0&&(n.default=e.defaultValue),e.options&&(e.type==="select"||e.type==="radio")&&(n.enum=e.options.map(o=>typeof o=="string"?o:o.value)),e.options&&e.type==="multiselect"&&(n.items={type:"string",enum:e.options.map(o=>typeof o=="string"?o:String(o.value))}),hi(n,e.validations),n}function fi(e){const i={},n=[],o=s=>{var d;for(const l of s){if(l.type==="section"&&l.children){o(l.children);continue}const u=vi(l);u&&(i[l.name]=u,(l.required||(d=l.validations)!=null&&d.some(m=>m.type==="required"))&&n.push(l.name))}};for(const s of e.sections)o(s.fields);const a={$schema:"http://json-schema.org/draft-07/schema#",$id:e.id,type:"object",title:e.title,description:e.description,properties:i,additionalProperties:!1};return n.length>0&&(a.required=n),a}function bt(e){const{t:i}=ke.useNiceTranslation(),{value:n,onChange:o,readOnly:a}=e,[s,d]=j.useState(()=>{try{return n===void 0?"":JSON.stringify(n,null,2)}catch{return""}}),[l,u]=j.useState(null);return j.useEffect(()=>{try{d(n===void 0?"":JSON.stringify(n,null,2))}catch{}},[JSON.stringify(n)]),t.jsxs("div",{className:"nice-schema-form__json-field",children:[t.jsx("textarea",{className:"nice-schema-form__json-textarea",value:s,readOnly:a,spellCheck:!1,rows:Math.min(12,Math.max(3,s.split(`
|
|
2
|
+
`).length)),onChange:m=>{const r=m.target.value;d(r);const c=r.trim();if(c===""){u(null),o(void 0);return}try{o(JSON.parse(c)),u(null)}catch(p){u(p instanceof Error?p.message:i("jsonSchemaToFormItems.invalidJson","Invalid JSON"))}}}),l&&t.jsx("div",{className:"nice-schema-form__json-error",children:l})]})}function gi(e){switch(e){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 yi(e,i,n,o={}){const a={field:e,label:i.title??e,required:n,hint:i.description,defaultValue:i.default};if(i.enum&&i.enum.length>0)return{...a,type:"select",options:i.enum.map(s=>({label:String(s),value:s}))};switch(i.type){case"number":case"integer":return{...a,type:"number"};case"boolean":return{...a,type:"checkbox"};case"string":return{...a,type:gi(i.format)};case"array":{const s=i.items;if(s!=null&&s.enum&&s.enum.length>0)return{...a,type:"tags",options:s.enum.map(d=>({label:String(d),value:String(d)}))};if((s==null?void 0:s.type)==="object"&&s.properties&&o.renderArrayField){const d=o.renderArrayField;return{...a,render:(l,u)=>d(l??[],u,s,a.label)}}return(s==null?void 0:s.type)==="string"||(s==null?void 0:s.type)==="number"||(s==null?void 0:s.type)==="integer"?{...a,type:"tags"}:{...a,render:(d,l)=>t.jsx(bt,{value:d,onChange:l})}}case"object":if(o.renderObjectField){const s=o.renderObjectField;return{...a,render:(d,l)=>s(d??{},l,i,a.label)}}return{...a,render:(s,d)=>t.jsx(bt,{value:s,onChange:d})};default:return{...a,type:"text"}}}function et(e,i={}){const{uiSchema:n,renderArrayField:o,renderObjectField:a}=i,s={renderArrayField:o,renderObjectField:a},d=e.properties??{},l=new Set(e.required??[]);return Object.keys(d).map(u=>{const m=yi(u,d[u],l.has(u),s);return n!=null&&n[u]?{...m,...n[u]}:m})}const Si={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 tt(e,i={}){var a,s;const{uiSchema:n}=i,o=[];for(const d of e){if(d.type==="section"&&d.children){for(const m of tt(d.children,i))o.push(d.label?{...m,group:d.label}:m);continue}const l=Si[d.type];if(!l)continue;const u={field:d.name,label:d.label,type:l,required:d.required||((a=d.validations)==null?void 0:a.some(m=>m.type==="required")),placeholder:d.placeholder,hint:d.helpText,defaultValue:d.defaultValue,disabled:d.disabled,readOnly:d.readonly,options:(s=d.options)==null?void 0:s.map(m=>typeof m=="string"?{label:m,value:m}:{label:m.label,value:m.value})};o.push(n!=null&&n[d.name]?{...u,...n[d.name]}:u)}return o}function xt(e){return e==null||e===""||Array.isArray(e)&&e.length===0}function it(e,i){const n=[],o=i.properties??{},a=new Set(i.required??[]);for(const s of Object.keys(o)){const d=o[s],l=e[s];if(a.has(s)&&xt(l)){n.push({field:s,message:`${d.title??s} is required`});continue}if(!xt(l)&&(d.enum&&!d.enum.includes(l)&&n.push({field:s,message:`${d.title??s} must be one of: ${d.enum.join(", ")}`}),(d.type==="number"||d.type==="integer")&&typeof l=="number"&&(d.minimum!==void 0&&l<d.minimum&&n.push({field:s,message:`${d.title??s} must be ≥ ${d.minimum}`}),d.maximum!==void 0&&l>d.maximum&&n.push({field:s,message:`${d.title??s} must be ≤ ${d.maximum}`})),d.type==="string"&&typeof l=="string"&&(d.minLength!==void 0&&l.length<d.minLength&&n.push({field:s,message:`${d.title??s} must be at least ${d.minLength} chars`}),d.maxLength!==void 0&&l.length>d.maxLength&&n.push({field:s,message:`${d.title??s} must be at most ${d.maxLength} chars`}),d.pattern)))try{new RegExp(d.pattern).test(l)||n.push({field:s,message:`${d.title??s} has an invalid format`})}catch{}}return n}const Ve="__nafRid";function ki(e){return Array.isArray(e)?`[${e.length}]`:e&&typeof e=="object"?"{…}":e==null?"":String(e)}const nt=j.forwardRef(function(i,n){const{value:o,defaultValue:a,onChange:s,itemSchema:d,title:l,readOnly:u=!1,columns:m,className:r,style:c,"data-testid":p}=i,[g,S]=h.useControllableState({value:o,defaultValue:a,fallbackValue:[],onChange:s,componentName:"NiceArrayField"}),f=d.properties??{},v=j.useMemo(()=>(m??Object.keys(f)).map(x=>{const w=f[x]??{},_={field:x,header:w.title??x};return w.type==="boolean"?(_.render=z=>z?t.jsx(h.NiceIcon,{name:"check",size:14,title:"true"}):"",_.align="center"):(w.type==="array"||w.type==="object")&&(_.render=z=>ki(z)),_}),[d,m]),y=j.useMemo(()=>et(d),[d]),b=j.useMemo(()=>g.map((k,x)=>({...k,[Ve]:String(x)})),[g]),M=k=>{const{[Ve]:x,...w}=k;return w},N="nice-array-field"+(r?` ${r}`:"");return t.jsx("div",{ref:n,className:N,style:c,"data-testid":p,children:t.jsx(h.NiceDataGrid,{data:b,keyField:Ve,columns:v,editMode:"popup",formItems:y,editFormTitle:l?`${l} — item`:"Edit item",emptyText:`No items${l?` in ${l}`:""}`,compact:!0,onRowAdd:u?void 0:k=>S([...g,M(k)]),onRowEdit:u?void 0:(k,x)=>{const w=Number(k);S(g.map((_,z)=>z===w?M(x):_))},onRowDelete:u?void 0:k=>{const x=Number(k);S(g.filter((w,_)=>_!==x))}})})}),bi=[{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 xi(e){const i=[],n=o=>{for(const a of o){if(a.type==="section"&&a.children){n(a.children);continue}a.required&&i.push({id:`${a.name}-required`,field:a.name,op:"required"});for(const s of a.validations??[])i.push({id:`${a.name}-${s.type}`,field:a.name,op:s.type,value:typeof s.value=="boolean"?void 0:s.value,message:s.message??(s.type==="required"?`${a.label??a.name} is required`:void 0)})}};return n(e),i}function ji(e,i){return h.evaluateValidation(xi(e),i).filter(n=>n.severity==="error").map(n=>({field:n.field,message:n.message}))}const Ie=j.forwardRef(function(i,n){const{schema:o,fields:a,uiSchema:s,value:d,defaultValue:l,onChange:u,onValidate:m,showJsonView:r=!1,columns:c=1,labelPosition:p="top",readOnly:g=!1,liveValidation:S=!0,validationRules:f,tutorial:v,className:y,style:b,id:M,"data-testid":N}=i,{t:k}=h.useNiceTranslation(),[x,w]=h.useControllableState({value:d,defaultValue:l,fallbackValue:{},onChange:u,componentName:"NiceSchemaForm"}),[_,z]=j.useState(!1),[K,C]=j.useState(""),[V,X]=j.useState(null),A=j.useMemo(()=>o?et(o,{uiSchema:s,renderArrayField:(R,H,Q,J)=>t.jsx(nt,{value:R,onChange:H,itemSchema:Q,title:J,readOnly:g})}):a?tt(a,{uiSchema:s}):[],[o,a,s,g]),ne=j.useMemo(()=>{const R=o?it(x,o):a?ji(a,x):[];if(f!=null&&f.length){const H=h.evaluateValidation(f,x).filter(Q=>Q.severity==="error").map(Q=>({field:Q.field,message:Q.message}));return[...R,...H]}return R},[o,a,x,f]);j.useEffect(()=>{m==null||m(ne)},[ne,m]),j.useEffect(()=>{if(_)try{C(JSON.stringify(x,null,2)),X(null)}catch{}},[_,x]);const T=(R,H)=>{w({...x,[R]:H})},L="nice-schema-form"+(y?` ${y}`:"");return t.jsxs("div",{ref:n,id:M,className:L,style:b,"data-testid":N,children:[v&&t.jsx("div",{className:"nice-schema-form__tutorial",children:t.jsx(h.NiceTutorialButton,{steps:h.resolveTutorial(v,bi)})}),r&&t.jsxs("div",{className:"nice-schema-form__toolbar","data-tour":"sf-viewtoggle",children:[t.jsx("button",{type:"button",className:"nice-schema-form__tab"+(_?"":" nice-schema-form__tab--active"),onClick:()=>z(!1),children:k("schemaForm.tab.form","Form")}),t.jsx(h.NiceTooltip,{content:k("schemaForm.tab.json.help","Edit the raw JSON value directly"),children:t.jsx("button",{type:"button",className:"nice-schema-form__tab"+(_?" nice-schema-form__tab--active":""),onClick:()=>z(!0),children:k("schemaForm.tab.json","JSON")})})]}),_?t.jsxs("div",{className:"nice-schema-form__json",children:[t.jsx("textarea",{className:"nice-schema-form__json-textarea",value:K,readOnly:g,spellCheck:!1,rows:Math.min(24,Math.max(6,K.split(`
|
|
3
|
+
`).length)),onChange:R=>{const H=R.target.value;C(H);try{const Q=JSON.parse(H);X(null),w(Q)}catch(Q){X(Q instanceof Error?Q.message:k("schemaForm.invalidJson","Invalid JSON"))}}}),V&&t.jsx("div",{className:"nice-schema-form__json-error",children:V})]}):t.jsx(h.NiceForm,{items:A,data:x,onFieldChange:T,columns:c,labelPosition:p,readOnly:g}),S&&ne.length>0&&t.jsx("ul",{className:"nice-schema-form__errors",role:"alert",children:ne.map((R,H)=>t.jsx("li",{className:"nice-schema-form__error",children:R.message},`${R.field}-${H}`))})]})}),Je="__eeFid",Ni={},Et={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"]},$t={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 Ue({title:e,help:i}){return t.jsxs("span",{className:"nice-entity-editor__field-label",children:[e,i?t.jsx(h.NiceTooltip,{content:i,children:t.jsx("span",{className:"nice-entity-editor__help",role:"img","aria-label":i,children:t.jsx(h.NiceIcon,{name:"info",size:14})})}):null]})}function wi({schema:e,value:i,onChange:n,readOnly:o}){const a=e.properties??{};return t.jsx("div",{className:"nice-entity-editor__field-form",children:Object.entries(a).map(([s,d])=>{const l=i[s],u=d.description,m=d.title??s;if(d.type==="boolean")return t.jsx("div",{className:"nice-entity-editor__field-row nice-entity-editor__field-row--check",children:t.jsx(h.NiceCheckbox,{label:t.jsx(Ue,{title:m,help:u}),checked:!!l,onChange:c=>n(s,c),disabled:o})},s);if(Array.isArray(d.enum)&&d.enum.length>0)return t.jsxs("div",{className:"nice-entity-editor__field-row",children:[t.jsx(Ue,{title:m,help:u}),t.jsx(h.NiceSelect,{options:d.enum.map(c=>({label:String(c),value:String(c)})),value:l==null?"":String(l),onChange:c=>n(s,c),clearable:!0,disabled:o})]},s);const r=d.type==="integer"||d.type==="number";return t.jsxs("div",{className:"nice-entity-editor__field-row",children:[t.jsx(Ue,{title:m,help:u}),t.jsx(h.NiceTextInput,{value:l==null?"":String(l),onChange:c=>n(s,r?c===""?void 0:Number(c):c),disabled:o})]},s)})})}function _i({fields:e,onChange:i,fieldSchema:n,readOnly:o}){const{t:a}=h.useNiceTranslation(),[s,d]=j.useState(null),l=j.useMemo(()=>e.map((c,p)=>({...c,[Je]:String(p)})),[e]),u=j.useMemo(()=>[{field:"name",header:a("entityEditor.field.name","Name"),sortable:!0,render:c=>t.jsx("span",{className:"nice-entity-editor__name",children:String(c??"")})},{field:"dataType",header:a("entityEditor.field.type","Type"),sortable:!0,render:c=>t.jsx(h.NiceBadge,{variant:"secondary",size:"sm",outline:!0,children:String(c??"—")})},{field:"__flags",header:a("entityEditor.field.flags","Constraints"),headerTooltip:a("entityEditor.field.flags.help","Key / required / unique / indexed constraints on this field"),render:(c,p)=>{const g=[[!!(p!=null&&p.isPrimaryKey),"PK",a("entityEditor.flag.pk","Primary key"),"info"],[!!(p!=null&&p.isForeignKey),"FK",a("entityEditor.flag.fk","Foreign key"),"info"],[!!(p!=null&&p.isRequired),"Req",a("entityEditor.flag.required","Required (NOT NULL)"),"warning"],[!!(p!=null&&p.isUnique),"Uniq",a("entityEditor.flag.unique","Unique"),"secondary"],[!!(p!=null&&p.isIndexed),"Idx",a("entityEditor.flag.indexed","Indexed"),"secondary"]];return t.jsx("span",{className:"nice-entity-editor__flags",children:g.filter(([S])=>S).map(([,S,f,v])=>t.jsx(h.NiceTooltip,{content:f,children:t.jsx(h.NiceBadge,{variant:v,size:"sm",children:S})},S))})}}],[]),m=(c,p,g)=>{i(e.map((S,f)=>f===c?{...S,[p]:g}:S))},r=()=>{const c=[...e,{name:`field${e.length+1}`,dataType:"string"}];i(c),d(c.length-1)};if(s!=null&&e[s]){const c=e[s];return t.jsxs("div",{className:"nice-entity-editor__field-detail",children:[t.jsxs("header",{className:"nice-entity-editor__edit-header",children:[t.jsx(h.NiceTooltip,{content:a("entityEditor.field.backHint","Back to the field list"),children:t.jsx(h.NiceButton,{variant:"ghost",size:"sm",leftIcon:t.jsx(h.NiceIcon,{name:"arrow-left",size:14}),onClick:()=>d(null),children:a("entityEditor.field.back","Fields")})}),t.jsx("span",{className:"nice-entity-editor__breadcrumb-sep",children:"/"}),t.jsx("span",{className:"nice-entity-editor__edit-title",children:String(c.name??a("entityEditor.field.untitled","New field"))})]}),t.jsx(wi,{schema:n,value:c,onChange:(p,g)=>m(s,p,g),readOnly:o}),t.jsx("div",{className:"nice-entity-editor__field-detail-actions",children:t.jsx(h.NiceButton,{variant:"primary",size:"sm",onClick:()=>d(null),children:a("entityEditor.field.done","Done")})})]})}return t.jsx(h.NiceDataGrid,{data:l,keyField:Je,columns:u,searchable:!0,searchPlaceholder:a("entityEditor.field.search","Search fields…"),emptyText:a("entityEditor.field.empty","No fields yet. Add one to define this entity."),onRowClick:c=>d(Number(c[Je])),onRowDelete:o?void 0:c=>i(e.filter((p,g)=>g!==Number(c))),toolbar:o?void 0:t.jsx(h.NiceButton,{variant:"primary",size:"sm",leftIcon:t.jsx(h.NiceIcon,{name:"plus",size:14}),onClick:r,children:a("entityEditor.field.add","Add field")}),compact:!0,striped:!0})}const st=j.forwardRef(function(i,n){const{value:o,defaultValue:a,onChange:s,entityMetaSchema:d=Et,fieldSchema:l=$t,fieldsKey:u="fields",validationsKey:m="validations",activeTab:r,defaultActiveTab:c="general",onActiveTabChange:p,extraTabs:g,readOnly:S=!1,className:f,style:v,id:y,"data-testid":b}=i,{t:M}=h.useNiceTranslation(),[N,k]=h.useControllableState({value:o,defaultValue:a,fallbackValue:Ni,onChange:s,componentName:"NiceEntityForm"}),[x,w]=h.useControllableState({value:r,defaultValue:c,fallbackValue:"general",onChange:p,componentName:"NiceEntityForm"}),_=j.useMemo(()=>{const A=N[u];return Array.isArray(A)?A:[]},[N,u]),z=j.useMemo(()=>{const A=T=>{const L=T.toLowerCase();return/(int|long|decimal|double|float|number|money)/.test(L)?"number":/bool/.test(L)?"boolean":/date|time/.test(L)?"date":"string"},ne=[];for(const T of _){const L=String(T.name??"");L&&ne.push({field:L,label:String(T.displayName??L),type:A(String(T.dataType??"string"))})}return ne},[_]),K=j.useMemo(()=>{const A=N[m];return Array.isArray(A)?A:[]},[N,m]),C=A=>{k({...N,...A})},V=[{id:"general",label:M("entityEditor.tab.general","General"),content:t.jsx(Ie,{schema:d,value:N,onChange:A=>C(A),columns:2,readOnly:S,liveValidation:!0})},{id:"fields",label:M("entityEditor.tab.fields","Fields"),badge:_.length||void 0,content:t.jsx(_i,{fields:_,onChange:A=>C({[u]:A}),fieldSchema:l,readOnly:S})},{id:"validation",label:M("entityEditor.tab.validation","Validation"),badge:K.length||void 0,content:t.jsx(h.NiceValidationBuilder,{fields:z,value:K,onChange:A=>C({[m]:A})})},...g??[]],X="nice-entity-form"+(f?` ${f}`:"");return t.jsx("div",{ref:n,id:y,className:X,style:v,"data-testid":b,children:t.jsx(h.NiceTabs,{tabs:V,activeTab:x,onChange:w,variant:"enclosed"})})}),Ge="__eeRid",Ii=[{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"}],Ft=j.forwardRef(function(i,n){const{value:o,defaultValue:a,onChange:s,entityMetaSchema:d=Et,fieldSchema:l=$t,fieldsKey:u="fields",validationsKey:m="validations",nameKey:r="name",renderErPreview:c,readOnly:p=!1,tutorial:g,className:S,style:f,id:v,"data-testid":y}=i,{t:b}=h.useNiceTranslation(),[M,N]=h.useControllableState({value:o,defaultValue:a,fallbackValue:[],onChange:s,componentName:"NiceEntityEditor"}),[k,x]=j.useState("list"),[w,_]=j.useState(0),[z,K]=j.useState("general"),C=Math.min(w,Math.max(0,M.length-1)),V=M[C],X=k==="edit"&&V!=null,A=j.useMemo(()=>M.map((J,U)=>({...J,[Ge]:String(U)})),[M]),ne=J=>{_(J),K("general"),x("edit")},T=()=>{const J=[...M,{[r]:`Entity${M.length+1}`,[u]:[]}];N(J),_(J.length-1),K("general"),x("edit")},L=J=>{N(M.filter((U,oe)=>oe!==J)),_(U=>U>=J?Math.max(0,U-1):U)},R=j.useMemo(()=>[{field:r,header:b("entityEditor.col.name","Name"),sortable:!0,render:J=>t.jsx("span",{className:"nice-entity-editor__name",children:String(J??"")})},{field:"displayName",header:b("entityEditor.col.displayName","Display name"),sortable:!0,render:J=>t.jsx("span",{className:"nice-entity-editor__muted",children:String(J??"—")})},{field:"tableName",header:b("entityEditor.col.table","Table"),sortable:!0,render:J=>t.jsx("span",{className:"nice-entity-editor__muted",children:String(J??"—")})},{field:u,header:b("entityEditor.col.fields","Fields"),align:"center",headerTooltip:b("entityEditor.col.fields.help","Number of fields defined on this entity"),render:J=>t.jsx(h.NiceBadge,{variant:"secondary",size:"sm",children:Array.isArray(J)?J.length:0})},{field:"__flags",header:b("entityEditor.col.flags","Flags"),render:(J,U)=>t.jsxs("span",{className:"nice-entity-editor__flags",children:[U!=null&&U.isAudited?t.jsx(h.NiceTooltip,{content:b("entityEditor.flag.audited","Audited — tracks who changed each record and when"),children:t.jsx(h.NiceBadge,{variant:"info",size:"sm",outline:!0,children:b("entityEditor.flag.audited.abbr","Audit")})}):null,U!=null&&U.isSoftDeleteEnabled?t.jsx(h.NiceTooltip,{content:b("entityEditor.flag.softDelete","Soft delete — rows are flagged deleted, never physically removed"),children:t.jsx(h.NiceBadge,{variant:"secondary",size:"sm",outline:!0,children:b("entityEditor.flag.softDelete.abbr","Soft-del")})}):null]})}],[r,u]),H=c?[{id:"er",label:b("entityEditor.tab.er","ER diagram"),content:t.jsx("div",{className:"nice-entity-editor__er",children:c(M)})}]:void 0,Q="nice-entity-editor"+(S?` ${S}`:"");return t.jsxs("div",{ref:n,id:v,className:Q,style:f,"data-testid":y,children:[g&&t.jsx("div",{className:"nice-entity-editor__tutorial",children:t.jsx(h.NiceTutorialButton,{steps:h.resolveTutorial(g,Ii)})}),X?t.jsxs("div",{className:"nice-entity-editor__edit",children:[t.jsxs("header",{className:"nice-entity-editor__edit-header",children:[t.jsx(h.NiceTooltip,{content:b("entityEditor.backHint","Back to the entity list"),children:t.jsx(h.NiceButton,{variant:"ghost",size:"sm",leftIcon:t.jsx(h.NiceIcon,{name:"arrow-left",size:14}),onClick:()=>x("list"),children:b("entityEditor.back","Entities")})}),t.jsx("span",{className:"nice-entity-editor__breadcrumb-sep",children:"/"}),t.jsx("span",{className:"nice-entity-editor__edit-title",children:String((V==null?void 0:V[r])??b("entityEditor.untitled","Untitled entity"))}),!p&&t.jsx(h.NiceTooltip,{content:b("entityEditor.deleteHint","Delete this entity"),children:t.jsx(h.NiceButton,{variant:"ghost",size:"sm",leftIcon:t.jsx(h.NiceIcon,{name:"trash",size:14}),onClick:()=>{L(C),x("list")},children:b("entityEditor.delete","Delete")})})]}),t.jsx(st,{value:V,onChange:J=>N(M.map((U,oe)=>oe===C?J:U)),entityMetaSchema:d,fieldSchema:l,fieldsKey:u,validationsKey:m,activeTab:z,onActiveTabChange:K,extraTabs:H,readOnly:p})]}):t.jsx("div",{className:"nice-entity-editor__list-view",children:t.jsx(h.NiceDataGrid,{data:A,keyField:Ge,columns:R,searchable:!0,searchPlaceholder:b("entityEditor.search","Search entities…"),emptyText:b("entityEditor.empty","No entities yet. Create one to get started."),onRowClick:J=>ne(Number(J[Ge])),onRowDelete:p?void 0:J=>L(Number(J)),toolbar:p?void 0:t.jsx(h.NiceButton,{variant:"primary",size:"sm",leftIcon:t.jsx(h.NiceIcon,{name:"plus",size:14}),onClick:T,children:b("entityEditor.new","New entity")}),compact:!0,striped:!0})})]})}),Ci=4e6;function Ti(e,i){const n=e.split(/\r?\n/),o=i.split(/\r?\n/);if(n.length*o.length>Ci)return[...n.map(r=>({type:"remove",text:r})),...o.map(r=>({type:"add",text:r}))];const a=n.length,s=o.length,d=Array.from({length:a+1},()=>new Uint32Array(s+1));for(let r=a-1;r>=0;r--)for(let c=s-1;c>=0;c--)d[r][c]=n[r]===o[c]?d[r+1][c+1]+1:Math.max(d[r+1][c],d[r][c+1]);const l=[];let u=0,m=0;for(;u<a&&m<s;)n[u]===o[m]?(l.push({type:"same",text:n[u]}),u++,m++):d[u+1][m]>=d[u][m+1]?l.push({type:"remove",text:n[u++]}):l.push({type:"add",text:o[m++]});for(;u<a;)l.push({type:"remove",text:n[u++]});for(;m<s;)l.push({type:"add",text:o[m++]});return l}function Mt({before:e,after:i,context:n=3}){const{t:o}=h.useNiceTranslation(),a=j.useMemo(()=>{const s=Ti(e,i),d=new Set;s.forEach((m,r)=>{if(m.type!=="same")for(let c=Math.max(0,r-n);c<=Math.min(s.length-1,r+n);c++)d.add(c)});const l=[];let u=0;return s.forEach((m,r)=>{d.has(r)?(u>0&&(l.push({type:"gap",count:u}),u=0),l.push(m)):u++}),u>0&&l.length>0&&l.push({type:"gap",count:u}),l},[e,i,n]);return a.length===0?t.jsx("p",{className:"nice-development-studio__muted",children:o("devStudio.diff.none","No changes.")}):t.jsx("pre",{className:"nice-development-studio__diff","aria-label":o("devStudio.diff.label","Changes"),children:a.map((s,d)=>s.type==="gap"?t.jsxs("span",{className:"nice-development-studio__diff-gap",children:[o("devStudio.diff.unchanged","{count} unchanged lines").replace("{count}",String(s.count)),`
|
|
4
4
|
`]},d):t.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
|
-
`]},d))})}function yi({open:e,onClose:i,session:n,preset:o,locales:a,prefill:s,onCreated:d}){var C,w,g,k;const{t:u}=h.useNiceTranslation(),l=n.workspaces.filter(x=>!x.readOnly),m=o.requiredLocales??[],[r,c]=j.useState(()=>{var x;return{workspaceId:s.workspaceId&&l.some(F=>F.id===s.workspaceId)?s.workspaceId:((x=l[0])==null?void 0:x.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([...m,...a.slice(0,2)])],views:!0,permissions:!0}}),[p,b]=j.useState(null),[f,v]=j.useState(!1),y=j.useMemo(()=>[...new Set((n.modulesByWs[r.workspaceId]??[]).map(x=>x.packageId).filter(Boolean))].sort(),[n.modulesByWs,r.workspaceId]);if(!e)return null;const S=new Set(Object.values(n.modulesByWs).flatMap(x=>x.map(F=>F.id))),N=async()=>{o.generateModule&&r.name.trim()&&b(await o.generateModule({...r,name:r.name.trim()},{existingIds:S}))};return t.jsx(h.NiceModal,{open:e,onClose:i,title:u("devStudio.wizard.title","New module"),size:"xl","data-testid":"studio-module-wizard",children:t.jsx(h.NiceWizard,{finishLabel:u("devStudio.wizard.create","Create module"),onCancel:i,onStepChange:x=>{x===3&&N()},onComplete:async()=>{if(f)return;v(!0);const x=await n.createModule({...r,name:r.name.trim()});v(!1),x&&(d({workspaceId:x.workspaceId,id:x.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:t.jsxs("div",{className:"nice-development-studio__form",children:[t.jsx(h.NiceSelect,{label:u("devStudio.wizard.workspace","Project"),value:r.workspaceId,options:l.map(x=>({value:x.id,label:x.label})),onChange:x=>c({...r,workspaceId:String(x)})}),t.jsx(h.NiceTextInput,{label:u("devStudio.wizard.package","Package"),value:r.packageId??"",placeholder:y.join(", "),onChange:x=>c({...r,packageId:x||void 0})}),t.jsx(h.NiceTextInput,{label:u("devStudio.wizard.name","Name"),value:r.name,placeholder:u("devStudio.wizard.namePlaceholder","e.g. Bike rental"),onChange:x=>c({...r,name:x})}),t.jsx(h.NiceTextInput,{label:u("devStudio.wizard.description","Description"),value:r.description??"",onChange:x=>c({...r,description:x||void 0})})]})},{id:"entities",title:u("devStudio.wizard.entities","Entities"),content:t.jsx(Tt,{value:r.entities,onChange:x=>c({...r,entities:x}),entityMetaSchema:(C=o.entities)==null?void 0:C.entityMetaSchema,fieldSchema:(w=o.entities)==null?void 0:w.fieldSchema,fieldsKey:(g=o.entities)==null?void 0:g.fieldsKey,nameKey:(k=o.entities)==null?void 0:k.nameKey})},{id:"options",title:u("devStudio.wizard.options","Options"),content:t.jsxs("div",{className:"nice-development-studio__form",children:[t.jsxs("fieldset",{className:"nice-development-studio__fieldset",children:[t.jsx("legend",{children:u("devStudio.wizard.locales","Languages")}),[...new Set([...m,...a])].map(x=>t.jsx(h.NiceCheckbox,{label:x,checked:r.locales.includes(x),disabled:m.includes(x),onChange:F=>c({...r,locales:F?[...r.locales,x]:r.locales.filter(L=>L!==x)})},x))]}),t.jsx(h.NiceCheckbox,{label:u("devStudio.wizard.views","A list and a form view per entity"),checked:!!r.views,onChange:x=>c({...r,views:x})}),t.jsx(h.NiceCheckbox,{label:u("devStudio.wizard.permissions","Viewer, editor and admin permissions"),checked:!!r.permissions,onChange:x=>c({...r,permissions:x})})]})},{id:"review",title:u("devStudio.wizard.review","Review"),content:p?t.jsxs("div",{children:[t.jsx("p",{children:u("devStudio.wizard.willCreate","Module {id} with these files:").replace("{id}",p.id)}),t.jsx("ul",{className:"nice-development-studio__list",children:p.files.map(x=>t.jsxs("li",{children:[t.jsx(h.NiceIcon,{name:"file",size:12})," ",x.path]},x.path))})]}):t.jsx("p",{className:"nice-development-studio__muted",children:u("devStudio.wizard.generating","Generating…")})}]})})}function gi({open:e,moduleLabel:i,changes:n,original:o,conflict:a,onSave:s,onOverwrite:d,onReload:u,onClose:l}){const{t:m}=h.useNiceTranslation();return e?t.jsxs(h.NiceModal,{open:e,onClose:l,size:"xl",title:m("devStudio.review.title","Save {module}").replace("{module}",i),"data-testid":"studio-review",footer:a?t.jsxs(t.Fragment,{children:[t.jsx(h.NiceButton,{variant:"ghost",onClick:l,children:m("devStudio.cancel","Cancel")}),t.jsx(h.NiceButton,{variant:"secondary",onClick:u,children:m("devStudio.review.reload","Reload theirs (drop mine)")}),t.jsx(h.NiceButton,{variant:"danger",onClick:d,children:m("devStudio.review.overwrite","Overwrite with mine")})]}):t.jsxs(t.Fragment,{children:[t.jsx(h.NiceButton,{variant:"ghost",onClick:l,children:m("devStudio.cancel","Cancel")}),t.jsx(h.NiceButton,{variant:"primary",onClick:s,children:m("devStudio.review.save","Save {count} files").replace("{count}",String(n.length))})]}),children:[a&&t.jsxs("p",{className:"nice-development-studio__error",role:"alert",children:[m("devStudio.review.conflict","These files changed since you opened them:")," ",a.conflicts.map(r=>r.path).join(", ")]}),n.map(r=>t.jsxs("section",{className:"nice-development-studio__source",children:[t.jsx("h4",{className:"nice-development-studio__source-title",children:r.type==="delete"?m("devStudio.change.delete","Delete {path}").replace("{path}",r.path):r.baseVersion===void 0&&!o(r.path)?m("devStudio.change.new","New file {path}").replace("{path}",r.path):r.path}),t.jsx(Ct,{before:o(r.path),after:r.type==="write"?r.text:""})]},r.path))]}):null}function bi({open:e,moduleId:i,templates:n,onApply:o,onClose:a}){const{t:s}=h.useNiceTranslation(),d=j.useMemo(()=>n.filter(c=>c.modules.some(p=>p.moduleId===i)).map(c=>c.id),[n,i]),[u,l]=j.useState(d);if(!e)return null;const m=n.map(c=>{var p,b;return{id:c.id,label:((p=c.translations.en)==null?void 0:p.name)??((b=Object.values(c.translations)[0])==null?void 0:b.name)??c.id}}),r=[{field:"label",header:s("devStudio.explorer.name","Name")}];return t.jsx(h.NiceModal,{open:e,onClose:a,title:s("devStudio.picker.title","Templates with {module}").replace("{module}",i),"data-testid":"studio-template-picker",footer:t.jsxs(t.Fragment,{children:[t.jsx(h.NiceButton,{variant:"ghost",onClick:a,children:s("devStudio.cancel","Cancel")}),t.jsx(h.NiceButton,{variant:"primary",onClick:()=>{const c=n.filter(p=>u.includes(p.id)!==d.includes(p.id)).map(p=>({...p,modules:u.includes(p.id)?[...p.modules,{moduleId:i}]:p.modules.filter(b=>b.moduleId!==i)}));o(c)},children:s("devStudio.apply","Apply")})]}),children:t.jsx(h.NiceTreeGrid,{data:m,columns:r,keyField:"id",sortable:!1,compact:!0,checkable:!0,checkedKeys:u,onCheckedChange:l,searchable:!0,"aria-label":s("devStudio.explorer.templates","Templates")})})}function gt({open:e,title:i,workspaces:n,workspaceId:o,idLabel:a,initialId:s="",withLabel:d,onSubmit:u,onClose:l}){var y;const{t:m}=h.useNiceTranslation(),[r,c]=j.useState(o??((y=n[0])==null?void 0:y.id)??""),[p,b]=j.useState(s),[f,v]=j.useState("");return e?t.jsx(h.NiceModal,{open:e,onClose:l,title:i,footer:t.jsxs(t.Fragment,{children:[t.jsx(h.NiceButton,{variant:"ghost",onClick:l,children:m("devStudio.cancel","Cancel")}),t.jsx(h.NiceButton,{variant:"primary",disabled:!p.trim()||!r,onClick:()=>u({workspaceId:r,id:p.trim(),label:f.trim()||p.trim()}),children:m("devStudio.ok","OK")})]}),children:t.jsxs("div",{className:"nice-development-studio__form",children:[t.jsx(h.NiceSelect,{label:m("devStudio.wizard.workspace","Project"),value:r,options:n.map(S=>({value:S.id,label:S.label})),onChange:S=>c(String(S))}),t.jsx(h.NiceTextInput,{label:a,value:p,onChange:b}),d&&t.jsx(h.NiceTextInput,{label:m("devStudio.package.label","Name"),value:f,onChange:v})]})}):null}const bt=e=>JSON.stringify(e??null,null,2);function nt({value:e,onChange:i,readOnly:n,height:o=320,label:a}){const{t:s}=h.useNiceTranslation(),[d,u]=j.useState(()=>bt(e)),[l,m]=j.useState(null),r=j.useRef(e);return j.useEffect(()=>{r.current!==e&&(r.current=e,u(bt(e)),m(null))},[e]),t.jsxs("div",{className:"nice-development-studio__json",role:"group","aria-label":a,children:[t.jsx(h.NiceSimpleCodeEditor,{value:d,language:"json",height:o,readOnly:n,lineNumbers:!0,onChange:c=>{u(c);try{const p=JSON.parse(c);m(null),r.current=p,i==null||i(p)}catch(p){m(p instanceof Error?p.message:String(p))}}}),l&&t.jsxs("p",{className:"nice-development-studio__error",role:"alert",children:[s("devStudio.json.invalid","Not valid JSON:")," ",l]})]})}const ki=[{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"}],st=j.forwardRef(function(i,n){const{value:o,defaultValue:a,onChange:s,locales:d,allowEditLocales:u=!0,allowEditKeys:l=!0,highlightMissing:m=!0,readOnly:r=!1,tutorial:c,className:p,style:b,id:f,"data-testid":v}=i,{t:y}=be.useNiceTranslation(),[S,N]=be.useControllableState({value:o,defaultValue:a,fallbackValue:{},onChange:s,componentName:"NiceI18nEditor"}),[C,w]=j.useState(""),[g,k]=j.useState(""),x=j.useMemo(()=>d??Object.keys(S),[d,S]),F=j.useMemo(()=>{const O=new Set;for(const P of Object.keys(S))for(const A of Object.keys(S[P]??{}))O.add(A);return[...O].sort()},[S]),L=(O,P,A)=>{N({...S,[O]:{...S[O]??{},[P]:A}})},K=(O,P)=>{if(!P||P===O)return;const A={};for(const te of Object.keys(S)){const X={...S[te]??{}};O in X&&(X[P]=X[O],delete X[O]),A[te]=X}N(A)},V=O=>{const P={};for(const A of Object.keys(S)){const te={...S[A]??{}};delete te[O],P[A]=te}N(P)},G=()=>{const O=C.trim();if(!O||F.includes(O))return;const P={};for(const A of x)P[A]={...S[A]??{},[O]:""};for(const A of Object.keys(S))P[A]||(P[A]=S[A]);N(P),w("")},Y=()=>{const O=g.trim();if(!O||S[O])return;const P={};for(const A of F)P[A]="";N({...S,[O]:P}),k("")},H=O=>{const P={...S};delete P[O],N(P)},$="nice-i18n-editor"+(p?` ${p}`:"");return t.jsxs("div",{ref:n,id:f,className:$,style:b,"data-testid":v,children:[c&&t.jsx("div",{className:"nice-i18n-editor__tutorial",children:t.jsx(be.NiceTutorialButton,{steps:be.resolveTutorial(c,ki)})}),t.jsx("div",{className:"nice-i18n-editor__scroll","data-tour":"i18n-grid",children:t.jsxs("table",{className:"nice-i18n-editor__table",children:[t.jsx("thead",{children:t.jsxs("tr",{children:[t.jsx("th",{className:"nice-i18n-editor__key-head",children:y("i18nEditor.keyHead","Key")}),x.map(O=>t.jsxs("th",{className:"nice-i18n-editor__locale-head",children:[t.jsx("span",{children:O}),u&&!r&&t.jsx("button",{type:"button",className:"nice-i18n-editor__locale-remove","aria-label":`${y("i18nEditor.removeLocale","Remove locale")} ${O}`,onClick:()=>H(O),children:t.jsx(be.NiceIcon,{name:"close",size:12})})]},O))]})}),t.jsxs("tbody",{children:[F.map(O=>t.jsxs("tr",{children:[t.jsxs("td",{className:"nice-i18n-editor__key-cell",children:[l&&!r?t.jsx("input",{className:"nice-i18n-editor__key-input",defaultValue:O,onBlur:P=>K(O,P.target.value.trim()),"aria-label":y("i18nEditor.keyAria","Translation key")}):t.jsx("span",{className:"nice-i18n-editor__key-text",children:O}),l&&!r&&t.jsx("button",{type:"button",className:"nice-i18n-editor__key-remove","aria-label":`${y("i18nEditor.removeKey","Remove key")} ${O}`,onClick:()=>V(O),children:t.jsx(be.NiceIcon,{name:"close",size:12})})]}),x.map(P=>{var X;const A=((X=S[P])==null?void 0:X[O])??"",te=m&&A==="";return t.jsx("td",{className:"nice-i18n-editor__cell",children:t.jsx("input",{className:"nice-i18n-editor__cell-input"+(te?" nice-i18n-editor__cell-input--missing":""),value:A,readOnly:r,onChange:D=>L(P,O,D.target.value),"aria-label":`${O} (${P})`})},P)})]},O)),F.length===0&&t.jsx("tr",{children:t.jsx("td",{className:"nice-i18n-editor__empty",colSpan:x.length+1,children:y("i18nEditor.empty","No translation keys yet.")})})]})]})}),!r&&(l||u)&&t.jsxs("div",{className:"nice-i18n-editor__toolbar","data-tour":"i18n-add",children:[l&&t.jsxs("div",{className:"nice-i18n-editor__add",children:[t.jsx("input",{className:"nice-i18n-editor__add-input",placeholder:y("i18nEditor.newKeyPlaceholder","new.key"),value:C,onChange:O=>w(O.target.value),onKeyDown:O=>{O.key==="Enter"&&G()},"aria-label":y("i18nEditor.newKeyAria","New key")}),t.jsxs("button",{type:"button",onClick:G,children:["+ ",y("i18nEditor.addKey","Key")]})]}),u&&t.jsxs("div",{className:"nice-i18n-editor__add",children:[t.jsx("input",{className:"nice-i18n-editor__add-input",placeholder:y("i18nEditor.newLocalePlaceholder","locale (e.g. de)"),value:g,onChange:O=>k(O.target.value),onKeyDown:O=>{O.key==="Enter"&&Y()},"aria-label":y("i18nEditor.newLocaleAria","New locale")}),t.jsxs("button",{type:"button",onClick:Y,children:["+ ",y("i18nEditor.addLocale","Locale")]})]})]})]})}),Q=e=>`${e.workspaceId}/${e.id}`;function Ge(e,i,n){const o=new Set(e.deleted),a=new Map;for(const p of e.files)o.has(p.path)||a.set(p.path,e.raw[p.path]!==void 0?{...p,text:e.raw[p.path]}:p);for(const[p,b]of Object.entries(e.raw))!a.has(p)&&!o.has(p)&&a.set(p,{path:p,text:b});const s=[...a.values()],d={moduleId:e.key.id,files:s,locales:n},u=T.buildDocuments(i.kinds,s,d),l=new Map(s.map(p=>[p.path,p.text])),m={};for(const p of u)if(p.key in e.drafts)try{const b=p.kind.encode(e.drafts[p.key],s.filter(f=>p.paths.includes(f.path)),d);for(const f of b.files)l.set(f.path,f.text),o.delete(f.path);for(const f of b.deleted??[])l.delete(f),o.add(f)}catch(b){m[p.key]=b instanceof Error?b.message:String(b)}const r=new Map(e.files.map(p=>[p.path,p])),c=[];for(const[p,b]of l){const f=r.get(p);(!f||f.text!==b)&&c.push({type:"write",path:p,text:b,baseVersion:f==null?void 0:f.version})}for(const p of o){const b=r.get(p);b&&c.push({type:"delete",path:p,baseVersion:b.version})}return{...e,working:s,documents:u,changes:c,pending:l,encodeErrors:m,dirty:c.length>0}}function Et(e,i){const n=[];for(const o of e.documents){if(o.error&&n.push({severity:"error",code:"file.unreadable",message:`${o.paths[0]} cannot be read: ${o.error}`,messageKey:"devStudio.issue.unreadable",params:{path:o.paths[0]},moduleId:e.key.id,path:o.paths[0]}),o.kind.editor!=="manifest"||!i.manifestSections)continue;const a=e.drafts[o.key]??o.model??{};for(const s of i.manifestSections){const{section:d}=T.fitManifestSection(s,a);if(d.schema)for(const u of et(a,d.schema))n.push({severity:"error",code:"manifest.schema",message:`${d.title}: ${u.field} — ${u.message}`,moduleId:e.key.id,path:o.paths[0],pointer:`/${u.field.replace(/\./g,"/")}`})}}for(const[o,a]of Object.entries(e.encodeErrors))n.push({severity:"error",code:"document.encode",message:`${o}: ${a}`,moduleId:e.key.id});if(i.validateModule){const o=[...e.pending.entries()].map(([a,s])=>({path:a,text:s}));n.push(...i.validateModule({key:e.key,files:o,documents:e.documents,contents:e.contents}).map(a=>({...a,moduleId:a.moduleId??e.key.id})))}return n}const xi=(e,i={})=>Object.entries(i).reduce((n,[o,a])=>n.split(`{${o}}`).join(String(a)),e),Si=e=>e instanceof Error?e.message:String(e);function ji(e,i,n){const[o,a]=j.useState([]),[s,d]=j.useState({}),u=j.useRef(s);u.current=s;const[l,m]=j.useState({}),[r,c]=j.useState(null),[p,b]=j.useState({}),[f,v]=j.useState({}),[y,S]=j.useState(0),[N,C]=j.useState([]),w=j.useRef({provider:e,preset:i,options:n});w.current={provider:e,preset:i,options:n};const g=j.useCallback((I,E,M)=>{var z,R;return xi(((R=(z=w.current.options).t)==null?void 0:R.call(z,I,E))??E,M)},[]),k=j.useCallback((I,E,M)=>{C(z=>[...z,{level:I,message:E,data:M,timestamp:Date.now()}].slice(-300))},[]),x=j.useCallback(async(I,E)=>{var M,z;S(R=>R+1);try{return await E()}catch(R){k("error",`${I}: ${Si(R)}`),(z=(M=w.current.options).onError)==null||z.call(M,R,I);return}finally{S(R=>R-1)}},[k]),F=j.useCallback(async()=>{const I=w.current.provider;I&&await x(g("devStudio.log.list","List"),async()=>{const E=await I.listWorkspaces();a(E);const M=await Promise.all(E.map(async z=>{const[R,U]=await Promise.all([I.listModules(z.id),I.listPackages?I.listPackages(z.id):Promise.resolve(void 0)]);return[z.id,R,U]}));d(Object.fromEntries(M.map(([z,R])=>[z,R]))),m(Object.fromEntries(M.filter(([,,z])=>z).map(([z,,R])=>[z,R]))),c(I.listTemplates?await I.listTemplates():null)})},[x,g]);j.useEffect(()=>{F()},[e,F]);const L=j.useMemo(()=>{const I={};for(const[E,M]of Object.entries(p))I[E]=Ge(M,i,n.locales);return I},[p,i,n.locales]),K=j.useCallback(async I=>{var ee,J;const E=Q(I),M=w.current.provider;if(!M)return;const z=await x(g("devStudio.log.open","Open {id}",{id:I.id}),()=>M.readModule(I));if(!z)return;const R=(J=(ee=u.current[I.workspaceId])==null?void 0:ee.find(ie=>ie.id===I.id))==null?void 0:J.contents,U={key:I,files:z,raw:{},deleted:[],drafts:{},contents:R};return b(ie=>ie[E]?ie:{...ie,[E]:U}),k("info",g("devStudio.log.opened","Opened {id} ({count} files)",{id:I.id,count:z.length})),Ge(U,w.current.preset,w.current.options.locales)},[x,k,g]),V=j.useCallback((I,E)=>{const M=Q(I);b(z=>z[M]?{...z,[M]:E(z[M])}:z)},[]),G=j.useCallback((I,E,M)=>V(I,z=>({...z,drafts:{...z.drafts,[E]:M}})),[V]),Y=j.useCallback((I,E,M,z=[])=>V(I,R=>{const U={...R.raw};M===null?delete U[E]:U[E]=M;const ee={...R.drafts};for(const J of z)delete ee[J];return{...R,raw:U,drafts:ee,deleted:R.deleted.filter(J=>J!==E)}}),[V]),H=j.useCallback((I,E)=>V(I,M=>{const z={...M.raw};delete z[E];const R=!M.files.some(U=>U.path===E);return{...M,raw:z,deleted:R?M.deleted:[...new Set([...M.deleted,E])]}}),[V]),$=j.useCallback(I=>V(I,E=>({...E,raw:{},deleted:[],drafts:{}})),[V]),O=j.useCallback(async I=>{const E=w.current.provider;if(!E)return;const M=await x(g("devStudio.log.reload","Reload {id}",{id:I.id}),()=>E.readModule(I));M&&(V(I,z=>({key:I,files:M,raw:{},deleted:[],drafts:{},contents:z.contents})),k("info",g("devStudio.log.reloaded","Reloaded {id}",{id:I.id})))},[x,V,k,g]),P=j.useCallback(I=>{const E=Q(I);b(M=>{const z={...M};return delete z[E],z})},[]),A=j.useCallback(async(I,E={})=>{var le;const M=w.current.provider,z=Q(I),R=p[z];if(!M||!R)return;const U=Ge(R,w.current.preset,w.current.options.locales);if(U.changes.length===0)return{ok:!0};const ee=E.force?U.changes.map(ne=>({...ne,baseVersion:void 0})):U.changes,J=await x(g("devStudio.log.save","Save {id}",{id:I.id}),()=>M.writeModule(I,ee));if(!J)return;if(!J.ok)return k("warn",g("devStudio.log.conflicts","{id}: {count} file(s) changed meanwhile",{id:I.id,count:J.conflicts.length})),J;const ie=[];for(const[ne,Ie]of U.pending){const je=R.files.find($e=>$e.path===ne);ie.push({...je,path:ne,text:Ie,version:((le=J.versions)==null?void 0:le[ne])??(je==null?void 0:je.version)})}V(I,ne=>({key:I,files:ie,raw:{},deleted:[],drafts:{},contents:ne.contents}));const Se=ee.map(ne=>ne.type==="delete"?g("devStudio.log.changeDelete","delete {path}",{path:ne.path}):g("devStudio.log.changeWrite","write {path}",{path:ne.path})).join(", ");return k("info",g("devStudio.log.saved","Saved {id}: {changes}",{id:I.id,changes:Se})),J},[p,x,V,k,g]),te=j.useCallback(async I=>{const E=Q(I),M=L[E];if(!M)return[];const z=Et(M,i),R=w.current.provider;let U=[];if(R!=null&&R.validate){const J=[...M.pending.entries()].map(([ie,Se])=>({path:ie,text:Se}));U=await x(g("devStudio.log.validate","Validate {id}",{id:I.id}),()=>R.validate(I,J))??[]}v(J=>({...J,[E]:U}));const ee=[...z,...U];k(ee.some(J=>J.severity==="error")?"warn":"info",ee.length===0?g("devStudio.log.noProblems","{id}: no problems",{id:I.id}):g("devStudio.log.problems","{id}: {count} problem(s)",{id:I.id,count:ee.length}));for(const J of ee)k(J.severity==="error"?"error":J.severity==="warning"?"warn":"info",`${J.path?`${J.path}: `:""}${J.messageKey?g(J.messageKey,J.message,J.params):J.message}`);return ee},[L,i,x,k,g]),X=j.useCallback(async I=>{const{provider:E,preset:M}=w.current;if(!(E!=null&&E.createModule)||!M.generateModule)return;const z=new Set(Object.values(s).flatMap(ee=>ee.map(J=>J.id))),R=await x(g("devStudio.log.generate","Generate module"),()=>M.generateModule(I,{existingIds:z}));if(!R)return;const U=await x(g("devStudio.log.create","Create {id}",{id:R.id}),()=>E.createModule({workspaceId:I.workspaceId,packageId:R.packageId??I.packageId,id:R.id,files:R.files}));return U&&(k("info",g("devStudio.log.created","Created {id}",{id:U.id})),await F()),U},[s,x,k,F,g]),D=j.useCallback(async(I,E)=>{const{provider:M,preset:z}=w.current;if(!(M!=null&&M.createModule)||!z.duplicateModule)return;const R=await x(g("devStudio.log.read","Read {id}",{id:I.id}),()=>M.readModule(I));if(!R)return;const U=await x(g("devStudio.log.duplicate","Duplicate"),()=>z.duplicateModule(R,E));if(!U)return;const ee=await x(g("devStudio.log.create","Create {id}",{id:U.id}),()=>M.createModule({workspaceId:E.workspaceId,packageId:U.packageId??E.packageId,id:U.id,files:U.files}));return ee&&(k("info",g("devStudio.log.duplicated","Duplicated {id} as {copy}",{id:I.id,copy:ee.id})),await F()),ee},[x,k,F,g]),Z=j.useCallback(async I=>{const E=w.current.provider;if(!(E!=null&&E.deleteModule))return!1;const M=await x(g("devStudio.log.delete","Delete {id}",{id:I.id}),async()=>(await E.deleteModule(I),!0));return M&&(P(I),k("info",g("devStudio.log.deleted","Deleted {id}",{id:I.id})),await F()),!!M},[x,P,k,F,g]),re=j.useCallback(async I=>{const E=w.current.provider;if(!(E!=null&&E.savePackage))return;const M=await x(g("devStudio.log.savePackage","Save package {id}",{id:I.id}),()=>E.savePackage(I));return M&&(k("info",g("devStudio.log.savedPackage","Saved package {id}",{id:M.id})),await F()),M},[x,k,F,g]),xe=j.useCallback(async(I,E)=>{const M=w.current.provider;if(!(M!=null&&M.saveTemplate))return;const z=await x(g("devStudio.log.saveTemplate","Save template {id}",{id:I.id}),()=>M.saveTemplate(I,E?{previousId:E}:void 0));return z&&M.listTemplates&&(c(await M.listTemplates()),k("info",g("devStudio.log.savedTemplate","Saved template {id}",{id:z.id}))),z},[x,k,g]),q=j.useCallback(async I=>{const E=w.current.provider;if(!(E!=null&&E.deleteTemplate))return!1;const M=await x(g("devStudio.log.deleteTemplate","Delete template {id}",{id:I}),async()=>(await E.deleteTemplate(I),!0));return M&&E.listTemplates&&(c(await E.listTemplates()),k("info",g("devStudio.log.deletedTemplate","Deleted template {id}",{id:I}))),!!M},[x,k,g]);return{workspaces:o,modulesByWs:s,packagesByWs:l,templates:r,modules:L,serverIssues:f,busy:y>0,logs:N,clearLogs:()=>C([]),log:k,refresh:F,openModule:K,close:P,setDraft:G,setRaw:Y,deleteFile:H,discard:$,reload:O,save:A,validate:te,createModule:X,duplicateModule:D,deleteModule:Z,savePackage:re,saveTemplate:xe,deleteTemplate:q}}const ue="__none",Be="t:",wi={entities:"entities",views:"views",workflows:"workflows",i18n:"translations",permissions:"permissions",rbac:"access",dataSources:"dataSources",seeds:"seeds",hooks:"hooks",script:"scripts"},Ni=["entities","views","workflows","translations","permissions","access","dataSources","seeds","hooks","scripts"],ot={entities:"database",views:"grid",workflows:"git-branch",translations:"globe",permissions:"shield",access:"users",dataSources:"server",seeds:"list",hooks:"zap",scripts:"code",files:"folder"},_i={views:"grid",workflows:"git-branch",dataSources:"server"},Mt=e=>e.kind.treeGroup??wi[e.kind.editor],$t=e=>e==="views"||e==="workflows"||e==="dataSources",ze=e=>Object.prototype.hasOwnProperty.call(ot,e),ye=(e,i)=>ze(e)?ot[e]:(i==null?void 0:i.icon)??"folder";function ge(e,i,n,o){const a=(s,d)=>e(s,d).replace("{count}",String(n??0));if(!ze(i)){const s=o?e(o.labelKey??`devStudio.group.${i}`,o.label):i;return n===void 0?s:`${s}: ${n}`}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 e("devStudio.group.translations","Translations");case"permissions":return e("devStudio.group.permissions","Permissions");case"access":return e("devStudio.group.access","Access");case"seeds":return e("devStudio.group.seeds","Seed data");case"hooks":return e("devStudio.group.hooks","Lifecycle hooks")}}function Ft(e){switch(e.kind){case"workspace":return`w|${e.workspaceId}`;case"package":return`p|${e.workspaceId}|${e.packageId??ue}`;case"module":return`m|${Q(e.module)}`;case"group":return`g|${Q(e.module)}|${e.group}${e.section?`|${e.section}`:""}`;case"section":return`s|${Q(e.module)}|${e.sectionId}`;case"folder":return`fo|${Q(e.module)}|${e.folderId}`;case"entity":return`e|${Q(e.module)}|${e.docKey}|${e.index}`;case"item":return`i|${Q(e.module)}|${e.group}|${e.docKey}|${e.itemKey}`;case"document":return`d|${Q(e.module)}|${e.docKey}`;case"panel":return`x|${Q(e.module)}|${e.panelKey}`;case"file":return`f|${Q(e.module)}|${e.path}`;case"templates":return"t";case"category":return`c|${e.category}`;case"template":return`t|${e.templateId}`;case"templateModule":return`tm|${e.templateId}|${e.moduleId}`}}const oe=(e,i)=>e.drafts[i.key]??i.model,me=(e,i)=>e.documents.find(n=>n.key===i),Ne=(e,i)=>e.changes.some(n=>i.paths.includes(n.path));function at(e){const i=[];for(const n of e.documents){if(n.kind.editor!=="entities")continue;const o=oe(e,n);Array.isArray(o)&&o.forEach((a,s)=>i.push({docKey:n.key,index:s,entity:a}))}return i}const Ye=e=>at(e).map(i=>i.entity),dt=(e,i="name")=>String(e.displayName||e[i]||"");function pe(e,i){const n=oe(e,i);return Array.isArray(n)?i.kind.editor==="dataSources"?n.map(o=>{const a=o;return{key:String(a.key??""),label:a.label||String(a.key??""),definition:o,source:o}}):n:[]}function rt(e,i,n){return n===null?e.filter((o,a)=>a!==i):e.map((o,a)=>a===i?n:o)}function Ot(e,i,n){return n===null?e.filter(o=>o.key!==i):e.map(o=>o.key===i?n:o)}function Kt(e,i,n){const o=new Map((i??[]).map(a=>[a.id,a]));for(const a of n){const s=a.packageId??ue;o.has(s)||o.set(s,{id:s,workspaceId:e,label:a.packageId??"",derived:!0})}return[...o.values()].sort((a,s)=>a.id===ue?1:s.id===ue?-1:a.label.localeCompare(s.label))}const Oe=(e,i)=>e&&/^[a-z0-9-]+$/.test(e)?e:i,kt=e=>e.slice(e.lastIndexOf("/")+1);function Bt(e){var n;const i=T.studioLayoutPath(e.working);return T.parseStudioLayout((n=e.working.find(o=>o.path===i))==null?void 0:n.text)}function Ii(e){const i=[...Ni],n=[...e??[]].filter(a=>!i.includes(a.id)).sort((a,s)=>(a.order??1e3)-(s.order??1e3)),o=[...i];for(const a of n){const s=a.order===void 0?o.length:Math.min(o.length,Math.max(0,Math.floor(a.order/10)));o.splice(s,0,a.id)}return o}function Ti(e,i,n){var r;const{t:o}=n,a=i.key,s=c=>{var p;return(p=n.groups)==null?void 0:p.find(b=>b.id===c)},d=new Map;for(const c of i.documents){const p=Mt(c);p&&d.set(p,[...d.get(p)??[],c])}const u=(c,p)=>({id:`${p}/d:${c.key}`,node:{kind:"document",module:a,docKey:c.key},label:kt(c.paths[0]??c.label),icon:"warning",noForm:!0,dirty:Ne(i,c)}),l=[];for(const c of Ii(n.groups)){const p=d.get(c);if(!p)continue;const b=s(c),f=`${e}/g:${c}`,v={kind:"group",module:a,group:c};if(c==="entities"){const y=[];for(const N of p){const C=oe(i,N);if(!Array.isArray(C)){y.push(u(N,f));continue}const w=Ne(i,N);C.forEach((g,k)=>{const x=g.fields;y.push({id:`${f}/e:${N.key}#${k}`,node:{kind:"entity",module:a,docKey:N.key,index:k},label:dt(g)||`#${k+1}`,icon:"table",info:Array.isArray(x)?String(x.length):void 0,dirty:w,search:String(g.name??""),ref:`entities:${String(g.name??`#${k}`)}`})})}const S=y.filter(N=>N.node.kind==="entity").length;l.push({id:f,node:v,label:ge(o,c,S),icon:ye(c,b),children:y});continue}if($t(c)){const y=[];for(const N of p){if(N.model===void 0){y.push(u(N,f));continue}const C=Ne(i,N);for(const w of pe(i,N))y.push({id:`${f}/i:${N.key}#${w.key}`,node:{kind:"item",module:a,group:c,docKey:N.key,itemKey:w.key},label:w.label||w.key,icon:_i[c],noForm:w.definition===void 0,dirty:C,search:w.key,ref:`${c}:${w.key}`})}const S=y.filter(N=>N.node.kind==="item").length;l.push({id:f,node:v,label:ge(o,c,S),icon:ye(c,b),children:y});continue}if(c==="scripts"||!ze(c)){l.push({id:f,node:v,label:ge(o,c,p.length,b),icon:ye(c,b),children:p.map(y=>({id:`${f}/d:${y.key}`,node:{kind:"document",module:a,docKey:y.key},label:kt(y.paths[0]??y.label),icon:c==="scripts"?"code":y.kind.icon??ye(c,b),noForm:y.model===void 0,dirty:Ne(i,y),search:y.paths.join(" "),ref:`${c}:${y.paths[0]??y.key}`}))});continue}if(p.length===1){const y=p[0];l.push({id:f,node:{kind:"document",module:a,docKey:y.key},label:ge(o,c),icon:ye(c,b),noForm:y.model===void 0,dirty:Ne(i,y)});continue}l.push({id:f,node:v,label:ge(o,c),icon:ye(c,b),children:p.map(y=>({id:`${f}/d:${y.key}`,node:{kind:"document",module:a,docKey:y.key},label:y.label,icon:ye(c,b),noForm:y.model===void 0,dirty:Ne(i,y),search:y.paths.join(" ")}))})}const m=Ei(e,i,l,Bt(i),(c,p)=>ge(o,c,p,s(c)));for(const c of((r=n.panels)==null?void 0:r.call(n,i))??[])m.push({id:`${e}/x:${c.key}`,node:{kind:"panel",module:a,panelKey:c.key},label:c.label,icon:"puzzle"});if(n.advanced){const c=new Set(i.changes.map(b=>b.path)),p=[...i.working].sort((b,f)=>b.path.localeCompare(f.path));m.push({id:`${e}/g:files`,node:{kind:"group",module:a,group:"files"},label:ge(o,"files",p.length),icon:ot.files,children:p.map(b=>({id:`${e}/g:files/f:${b.path}`,node:{kind:"file",module:a,path:b.path},label:b.path,icon:"file",dirty:c.has(b.path)}))})}return m}const Ci=new Set(["entities","views","workflows","dataSources","scripts"]),Ke=e=>e.reduce((i,n)=>i+(n.node.kind==="folder"?Ke(n.children??[]):n.ref?1:0),0);function Ei(e,i,n,o,a){var b;if(T.isEmptyStudioLayout(o))return n;const s=i.key,d=new Set(o.sections.map(f=>f.id)),u=f=>{var v;return(f.ref?(v=o.placement[f.ref])==null?void 0:v.order:void 0)??Number.MAX_SAFE_INTEGER},l=f=>f.some(v=>{var y;return v.ref&&((y=o.placement[v.ref])==null?void 0:y.order)!==void 0})?[...f].sort((v,y)=>u(v)-u(y)):f,m=(f,v,y,S,N)=>{var L;const C=o.folders.filter(K=>K.group===y&&(K.section&&d.has(K.section)?K.section:void 0)===S),w=new Set(C.map(K=>K.id)),g=K=>V=>({...V,id:`${K}${V.id.startsWith(v)?V.id.slice(v.length):`/${V.id}`}`}),k=new Map,x=[];for(const K of N){const V=K.ref?(L=o.placement[K.ref])==null?void 0:L.folder:void 0;V&&w.has(V)?k.set(V,[...k.get(V)??[],K]):x.push(K)}const F=(K,V)=>C.filter(G=>(G.parent&&w.has(G.parent)?G.parent:void 0)===K).map(G=>{const Y=`${V}/fo:${G.id}`,H=[...F(G.id,Y),...l(k.get(G.id)??[]).map(g(Y))];return{id:Y,node:{kind:"folder",module:s,folderId:G.id,group:y},label:G.label,icon:"folder",info:String(Ke(H)),children:H}});return[...F(void 0,f),...l(x).map(g(f))]},r=[],c=new Map(o.sections.map(f=>[f.id,[]]));for(const f of n){if(f.node.kind!=="group"||!f.children){r.push(f);continue}const v=f.node.group,y=new Map;for(const N of f.children){const C=N.ref?(b=o.placement[N.ref])==null?void 0:b.section:void 0,w=C&&d.has(C)?C:void 0;y.set(w,[...y.get(w)??[],N])}const S=m(f.id,f.id,v,void 0,y.get(void 0)??[]);r.push({...f,label:p(f,v,S),children:S});for(const N of o.sections){const C=y.get(N.id)??[],w=o.folders.some(x=>x.group===v&&x.section===N.id);if(C.length===0&&!w)continue;const g=`${e}/s:${N.id}/g:${v}`,k=m(g,f.id,v,N.id,C);c.get(N.id).push({...f,id:g,node:{kind:"group",module:s,group:v,section:N.id},label:p(f,v,k),children:k})}}for(const f of o.sections){const v=c.get(f.id)??[];r.push({id:`${e}/s:${f.id}`,node:{kind:"section",module:s,sectionId:f.id},label:f.label,icon:"layers",info:String(v.reduce((y,S)=>y+Ke(S.children??[]),0)),children:v})}return r;function p(f,v,y){return Ci.has(v)||!ze(v)?a(v,Ke(y)):f.label}}function Xe(e){const i=e.label||e.id;return i===e.id&&e.id.includes("/")?e.id.slice(e.id.lastIndexOf("/")+1):i}const Ue=e=>e.parentId??(e.id.includes("/")?e.id.slice(0,e.id.lastIndexOf("/")):void 0);function Mi(e,i,n,o){const a=new Map(n.map(m=>[m.id,m]));for(const m of n){let r=Ue(m);for(;r&&!a.has(r);){const c={id:r,workspaceId:e,label:"",derived:!0};a.set(r,c),r=Ue(c)}}const s=[...a.values()],d=m=>{const r=Ue(m);return r&&a.has(r)&&r!==m.id?r:void 0},u=m=>m.sort((r,c)=>r.id===ue?1:c.id===ue?-1:Xe(r).localeCompare(Xe(c))),l=(m,r)=>u(s.filter(c=>d(c)===m)).map(c=>{const p=`${r}/p:${c.id}`;return o(c,p,l(c.id,p))});return l(void 0,i)}function $i(e){const{t:i}=e,n=i("devStudio.explorer.noPackage","No package"),o=e.workspaces.map(l=>{const m=e.modulesByWs[l.id]??[],r=`w:${l.id}`;return{id:r,node:{kind:"workspace",workspaceId:l.id},label:l.label,icon:Oe(l.icon,"folder"),info:String(m.length),readOnly:l.readOnly,search:l.id,children:Mi(l.id,r,Kt(l.id,e.packagesByWs[l.id],m),(c,p,b)=>{const f=m.filter(v=>(v.packageId??ue)===c.id).sort((v,y)=>v.label.localeCompare(y.label));return{id:p,node:{kind:"package",workspaceId:l.id,packageId:c.id===ue?void 0:c.id},label:c.id===ue?n:Xe(c),icon:Oe(c.icon,"archive"),info:String(f.length),search:c.id,children:[...b,...f.map(v=>{var g;const y=Q(v),S=e.modules[y],N=`${p}/m:${v.id}`,C=S?Ti(N,S,e):void 0,w=S?[...at(S).map(k=>`${k.entity.name??""} ${dt(k.entity)}`),...S.documents.filter(k=>k.kind.editor==="views").flatMap(k=>pe(S,k).map(x=>`${x.key} ${x.label}`))]:[];return{id:N,node:{kind:"module",module:{workspaceId:v.workspaceId,id:v.id}},label:v.label,icon:Oe(v.icon,"box"),info:v.version,readOnly:v.readOnly,shadowedBy:v.shadowedBy,dirty:S==null?void 0:S.dirty,issues:(g=e.issueCounts)==null?void 0:g[y],search:[v.id,v.description??"",v.search??"",...w].join(" "),children:C}})]}})}});if(e.templates){const l=new Map;for(const c of e.workspaces)for(const p of e.modulesByWs[c.id]??[])l.has(p.id)||l.set(p.id,p);const m=new Map;for(const c of e.templates){const p=c.category??"";m.set(p,[...m.get(p)??[],c])}const r=c=>{var p,b;return((p=c.translations.en)==null?void 0:p.name)??((b=Object.values(c.translations)[0])==null?void 0:b.name)??c.id};o.push({id:Be,node:{kind:"templates"},label:i("devStudio.tree.templates","Templates"),icon:"layers",info:String(e.templates.length),children:[...m.entries()].sort(([c],[p])=>c.localeCompare(p)).map(([c,p])=>{const b=`${Be}/c:${c}`;return{id:b,node:{kind:"category",category:c},label:c||i("devStudio.explorer.noCategory","Other"),icon:"folder",info:String(p.length),children:[...p].sort((f,v)=>(f.sortOrder??0)-(v.sortOrder??0)||r(f).localeCompare(r(v))).map(f=>{const v=`${b}/t:${f.id}`;return{id:v,node:{kind:"template",templateId:f.id},label:r(f),icon:Oe(f.icon,"layers"),info:String(f.modules.length),readOnly:f.readOnly,search:`${f.id} ${(f.tags??[]).join(" ")}`,children:f.modules.map(y=>{const S=l.get(y.moduleId);return{id:`${v}/m:${y.moduleId}`,node:{kind:"templateModule",templateId:f.id,moduleId:y.moduleId,target:S?{workspaceId:S.workspaceId,id:S.id}:void 0},label:(S==null?void 0:S.label)??y.moduleId,icon:"box",info:y.required?i("devStudio.template.required","required"):void 0,missing:!S,search:y.moduleId}})}})}})})}const a=new Map,s=new Map,d=new Map,u=(l,m,r=0)=>{for(const c of l){c.depth=r,a.set(c.id,c),m&&s.set(c.id,m);const p=Ft(c.node);d.has(p)||d.set(p,c.id),c.children&&u(c.children,c.id,r+1)}};return u(o),{rows:o,byId:a,parentOf:s,rowOfNode:d}}function xt(e,i){const n=[];let o=i;for(;o;){const a=e.byId.get(o);if(!a)break;n.unshift(a),o=e.parentOf.get(o)}return n}const He=(e,i)=>e.rowOfNode.get(Ft(i));function Ee(e){return"module"in e?e.module:void 0}function Fi(e,i){var o;const n="module"in e?i.modules[Q(e.module)]:void 0;switch(e.kind){case"module":return n!=null&&n.documents.some(a=>a.kind.editor==="manifest")?{kind:"manifest",module:e.module}:void 0;case"entity":return{kind:"entity",module:e.module,docKey:e.docKey,index:e.index};case"item":{const a=n&&me(n,e.docKey),s=a&&pe(n,a).find(d=>d.key===e.itemKey);return(s==null?void 0:s.definition)!==void 0||i.advanced?{...e}:void 0}case"document":{const a=n&&me(n,e.docKey);return(a==null?void 0:a.model)!==void 0?{kind:"document",module:e.module,docKey:e.docKey}:a&&i.advanced?{kind:"file",module:e.module,path:a.paths[0]}:void 0}case"panel":return{kind:"panel",module:e.module,panelKey:e.panelKey};case"file":return{kind:"file",module:e.module,path:e.path};case"package":{const a=(o=i.packages)==null?void 0:o.find(s=>s.id===e.packageId);return a&&!a.derived?{kind:"package",pkg:a}:void 0}case"template":return{kind:"template",templateId:e.templateId};default:return}}function St(e){switch(e.kind){case"manifest":case"problems":case"history":return{kind:"module",module:e.module};case"entity":return{kind:"entity",module:e.module,docKey:e.docKey,index:e.index};case"item":return{...e};case"document":return{kind:"document",module:e.module,docKey:e.docKey};case"panel":return{kind:"panel",module:e.module,panelKey:e.panelKey};case"file":return{kind:"file",module:e.module,path:e.path};case"package":return{kind:"package",workspaceId:e.pkg.workspaceId,packageId:e.pkg.id};case"template":return e.templateId?{kind:"template",templateId:e.templateId}:void 0}}const Oi=/^\/(?:[A-Za-z]+\/)?(\d+)(?:\/|$)/;function zt(e,i){const n=e.key,o=i.path?e.documents.find(u=>u.paths.includes(i.path)):void 0;if(!o)return{kind:"module",module:n};const a=Mt(o),s=o.paths.length===1?Oi.exec(i.pointer??""):null,d=s?Number(s[1]):-1;if(a==="entities"){const u=oe(e,o);return Array.isArray(u)&&d>=0&&d<u.length?{kind:"entity",module:n,docKey:o.key,index:d}:{kind:"group",module:n,group:a}}if($t(a)){const u=d>=0?pe(e,o)[d]:void 0;return u?{kind:"item",module:n,group:a,docKey:o.key,itemKey:u.key}:{kind:"group",module:n,group:a}}return a?{kind:"document",module:n,docKey:o.key}:o.kind.editor==="manifest"?{kind:"module",module:n}:{kind:"file",module:n,path:o.paths[0]}}function jt(e){var m,r;const{module:i,doc:n,preset:o,session:a,locales:s,readOnly:d}=e,u=oe(i,n),l=c=>a.setDraft(i.key,n.key,c);switch(n.kind.editor){case"manifest":return t.jsx(Ki,{...e});case"i18n":{const c=u??{};return t.jsx(st,{value:c,onChange:l,locales:[...new Set([...s,...Object.keys(c)])],allowEditLocales:!0,allowEditKeys:!0,highlightMissing:!0,readOnly:d})}case"permissions":return t.jsx(Bi,{value:u??{permissions:[],groups:[]},onChange:l,readOnly:d});case"seeds":return t.jsx(Di,{value:u??{seeds:{}},onChange:l,entities:Ye(i),readOnly:d});case"rbac":return t.jsx(h.NiceAccessManager,{value:u,onChange:l,readOnly:d});case"hooks":return t.jsx(h.NiceLifecycleHooksEditor,{triggers:((m=o.hooks)==null?void 0:m.triggers)??[],handlers:(r=o.hooks)==null?void 0:r.handlers,bindings:u??[],onChange:l,groupByTrigger:!0,allowCondition:!0,readOnly:d});case"script":return e.scriptRunner?t.jsx(h.NiceScriptRunner,{...e.scriptRunner,value:String(u??""),onChange:l}):t.jsx(h.NiceSimpleCodeEditor,{value:String(u??""),onChange:l,language:"javascript",height:"100%",lineNumbers:!0,readOnly:d});case"text":return t.jsx(h.NiceSimpleCodeEditor,{value:String(u??""),onChange:l,height:"100%",lineNumbers:!0,readOnly:d});default:return t.jsx(nt,{value:u,onChange:l,readOnly:d,height:"100%",label:n.label})}}function Ki({module:e,doc:i,preset:n,session:o,readOnly:a,advanced:s}){var C;const{t:d}=h.useNiceTranslation(),u=oe(e,i),l=j.useMemo(()=>u??{},[u]),m=w=>o.setDraft(e.key,i.key,w),r=n.manifestSections,c=j.useMemo(()=>(r??[]).map(w=>T.fitManifestSection(w,l)),[r,l]),p=r??[],b=j.useMemo(()=>new Set(c.flatMap(w=>w.keys)),[c]),f=Object.keys(l).filter(w=>!b.has(w)),[v,y]=j.useState(((C=c[0])==null?void 0:C.section.id)??"__other"),S=c.find(w=>w.section.id===v),N=s?t.jsx(nt,{value:Object.fromEntries(f.map(w=>[w,l[w]])),readOnly:a,label:d("devStudio.manifest.other","Other properties"),onChange:w=>{if(w&&typeof w=="object"&&!Array.isArray(w)){const g=Object.fromEntries(Object.entries(l).filter(([k])=>b.has(k)));m({...g,...w})}}}):t.jsxs("div",{className:"nice-development-studio__note",children:[t.jsx("p",{children:d("devStudio.manifest.kept","These properties have no form here. Saving keeps them exactly as they are; switch to the advanced mode to edit them.")}),t.jsx("ul",{className:"nice-development-studio__chips",children:f.map(w=>t.jsx("li",{className:"nice-development-studio__tag",children:w},w))})]});return t.jsxs("div",{className:"nice-development-studio__sections","data-testid":"studio-manifest-form",children:[t.jsxs("nav",{className:"nice-development-studio__section-nav","aria-label":d("devStudio.manifest.sections","Sections"),children:[c.map(({section:w})=>t.jsx(h.NiceButton,{size:"sm",variant:v===w.id?"primary":"ghost","aria-pressed":v===w.id,onClick:()=>y(w.id),children:w.title},w.id)),f.length>0&&t.jsx(h.NiceButton,{size:"sm",variant:v==="__other"?"primary":"ghost","aria-pressed":v==="__other",onClick:()=>y("__other"),children:`${d("devStudio.manifest.other","Other properties")} (${f.length})`})]}),t.jsx("div",{className:"nice-development-studio__section-body",children:S?t.jsx(_e,{schema:S.section.schema,fields:S.section.fields,uiSchema:S.section.uiSchema,value:Object.fromEntries(S.keys.filter(w=>w in l).map(w=>[w,l[w]])),onChange:w=>{const g={...l};for(const k of S.keys)w[k]===void 0?delete g[k]:g[k]=w[k];m(g)},readOnly:a}):f.length>0||p.length===0?N:null})]})}function Bi({value:e,onChange:i,readOnly:n}){const{t:o}=h.useNiceTranslation(),a={code:o("devStudio.permissions.code","Code"),name:o("devStudio.permissions.name","Name"),description:o("devStudio.permissions.description","Description")},s=j.useMemo(()=>{const u={};for(const l of e.groups)for(const m of l.permissions)u[`${l.id}:${m}`]=!0;return u},[e.groups]),d=(u,l)=>{const m=e.permissions[u],r={...m,...l};i({permissions:e.permissions.map((c,p)=>p===u?r:c),groups:l.code!==void 0&&l.code!==m.code?e.groups.map(c=>({...c,permissions:c.permissions.map(p=>p===m.code?r.code:p)})):e.groups})};return t.jsxs("div",{className:"nice-development-studio__permissions",children:[t.jsx("h4",{children:o("devStudio.permissions.codes","Permissions")}),t.jsxs("table",{className:"nice-development-studio__table",children:[t.jsx("thead",{children:t.jsxs("tr",{children:[t.jsx("th",{children:a.code}),t.jsx("th",{children:a.name}),t.jsx("th",{children:a.description}),!n&&t.jsx("th",{"aria-label":o("devStudio.delete","Delete")})]})}),t.jsx("tbody",{children:e.permissions.map((u,l)=>t.jsxs("tr",{children:[["code","name","description"].map(m=>t.jsx("td",{children:t.jsx("input",{className:"nice-development-studio__cell",value:u[m]??"",readOnly:n,"aria-label":`${a[m]} ${u.code}`,onChange:r=>d(l,{[m]:r.target.value})})},m)),!n&&t.jsx("td",{children:t.jsx(h.NiceButton,{size:"sm",variant:"ghost",ariaLabel:`${o("devStudio.delete","Delete")} ${u.code}`,onClick:()=>i({permissions:e.permissions.filter((m,r)=>r!==l),groups:e.groups.map(m=>({...m,permissions:m.permissions.filter(r=>r!==u.code)}))}),children:t.jsx(h.NiceIcon,{name:"trash",size:14})})})]},l))})]}),!n&&t.jsxs("div",{className:"nice-development-studio__row",children:[t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:t.jsx(h.NiceIcon,{name:"plus",size:14}),onClick:()=>i({...e,permissions:[...e.permissions,{code:`New.Permission${e.permissions.length+1}`}]}),children:o("devStudio.permissions.addCode","New permission")}),t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:t.jsx(h.NiceIcon,{name:"plus",size:14}),onClick:()=>i({...e,groups:[...e.groups,{id:`group${e.groups.length+1}`,label:o("devStudio.permissions.newGroup","Group {n}").replace("{n}",String(e.groups.length+1)),permissions:[]}]}),children:o("devStudio.permissions.addGroup","New group")})]}),t.jsx("h4",{children:o("devStudio.permissions.groups","Groups")}),t.jsx(h.NicePermissionMatrix,{roles:e.groups.map(u=>({id:u.id,label:u.label})),actions:e.permissions.map(u=>({id:u.code,label:u.name||u.code})),value:s,readOnly:n,showBulkActions:!0,onChange:u=>i({...e,groups:e.groups.map(l=>({...l,permissions:e.permissions.map(m=>m.code).filter(m=>u[`${l.id}:${m}`]===!0)}))})})]})}const wt=e=>e===null||typeof e!="object";function zi(e){const i=e.toLowerCase();return/(int|long|decimal|double|float|number|money)/.test(i)?"number":/bool/.test(i)?"boolean":"string"}function Pi(e,i){const n={},o=Array.isArray(i==null?void 0:i.fields)?i.fields:[];for(const a of o){const s=String(a.name??"");s&&e.every(d=>wt(d[s]))&&(n[s]={type:zi(String(a.dataType??a.type??"string")),title:String(a.displayName||s)})}for(const a of e)for(const[s,d]of Object.entries(a))!(s in n)&&e.every(u=>wt(u[s]))&&(n[s]={type:typeof d=="number"?"number":typeof d=="boolean"?"boolean":"string",title:s});return{type:"object",properties:n}}function Di({value:e,onChange:i,entities:n,readOnly:o}){const{t:a}=h.useNiceTranslation(),s=u=>n.find(l=>l.name===u||l.tableName===u),d=u=>{const l=e[u]??{},m=Object.keys(l);return m.length===0?t.jsx("p",{className:"nice-development-studio__muted",children:a("devStudio.seeds.empty","No rows.")}):t.jsx(h.NiceTabs,{tabs:m.map(r=>{const c=l[r];return{id:r,label:`${r} (${c.length})`,content:t.jsx(tt,{value:c,itemSchema:Pi(c,s(r)),title:r,readOnly:o,onChange:p=>{const b=p.length===c.length?p.map((f,v)=>f===c[v]?f:{...c[v],...f}):p;i({...e,[u]:{...l,[r]:b}})}})}})})};return t.jsx(h.NiceTabs,{tabs:[{id:"seeds",label:a("devStudio.seeds.data","Data"),content:d("seeds")},{id:"demo",label:a("devStudio.seeds.demo","Demo data"),content:d("demoSeeds")}]})}function Ri({module:e,path:i,session:n,readOnly:o}){var r;const{t:a}=h.useNiceTranslation(),[s,d]=j.useState("source"),u=e.changes.find(c=>c.path===i),l=e.documents.filter(c=>c.paths.includes(i)).map(c=>c.key),m=((r=e.files.find(c=>c.path===i))==null?void 0:r.text)??"";return t.jsxs("div",{className:"nice-development-studio__source","data-testid":"studio-file-source",children:[t.jsx("div",{className:"nice-development-studio__row",children:t.jsxs("div",{className:"nice-development-studio__segmented",role:"group","aria-label":a("devStudio.doc.mode","Show"),children:[t.jsx(h.NiceButton,{size:"sm",variant:s==="source"?"primary":"ghost","aria-pressed":s==="source",onClick:()=>d("source"),children:a("devStudio.doc.source","Source")}),t.jsx(h.NiceButton,{size:"sm",variant:s==="changes"?"primary":"ghost","aria-pressed":s==="changes",onClick:()=>d("changes"),children:`${a("devStudio.doc.changes","Changes")}${u?" (1)":""}`})]})}),s==="source"?t.jsx(h.NiceSimpleCodeEditor,{value:e.pending.get(i)??"",language:i.endsWith(".json")?"json":i.endsWith(".js")?"javascript":"plaintext",height:"100%",lineNumbers:!0,readOnly:o,onChange:c=>n.setRaw(e.key,i,T.keepTextFormat(c,e.pending.get(i)),l)}):u?t.jsx(Ct,{before:m,after:u.type==="write"?u.text:""}):t.jsx("p",{className:"nice-development-studio__muted",children:a("devStudio.diff.none","No changes.")})]})}const Li=e=>({type:"object",required:["id"],properties:{id:{type:"string",title:e("devStudio.template.id","Id (slug)")},category:{type:"string",title:e("devStudio.template.category","Category")},subCategory:{type:"string",title:e("devStudio.template.subCategory","Subcategory")},parentId:{type:"string",title:e("devStudio.template.parent","Parent template")},icon:{type:"string",title:e("devStudio.template.icon","Icon")},sortOrder:{type:"number",title:e("devStudio.template.sortOrder","Order")},tags:{type:"array",items:{type:"string"},title:e("devStudio.template.tags","Tags")}}});function Ai({session:e,template:i,locales:n,extraSchema:o,readOnly:a,onSaved:s,onDeleted:d}){var w;const{t:u}=h.useNiceTranslation(),[l,m]=j.useState(()=>i??{id:"",translations:{[n[0]??"en"]:{name:""}},modules:[]}),[r,c]=j.useState(null),p=a||!!(i!=null&&i.readOnly),b={id:l.id,category:l.category,subCategory:l.subCategory,parentId:l.parentId,icon:l.icon,sortOrder:l.sortOrder,tags:l.tags},f=Object.fromEntries(Object.entries(l.translations).map(([g,k])=>[g,{name:k.name,description:k.description??""}])),v=j.useMemo(()=>e.workspaces.map(g=>{const k=e.modulesByWs[g.id]??[],x=[...new Set(k.map(F=>F.packageId??""))].sort();return{id:`w:${g.id}`,label:g.label,kind:"workspace",children:x.map(F=>({id:`w:${g.id}/p:${F}`,label:F||u("devStudio.explorer.noPackage","No package"),kind:"package",children:k.filter(L=>(L.packageId??"")===F).map(L=>({id:`m:${L.id}`,label:L.label,kind:"module"}))}))}}),[e.workspaces,e.modulesByWs,u]),y=j.useMemo(()=>{const g=new Map;for(const k of Object.values(e.modulesByWs))for(const x of k)g.set(x.id,x.label);return g},[e.modulesByWs]),S=g=>m({...l,modules:g}),N=(g,k)=>{const x=[...l.modules],[F]=x.splice(g,1);x.splice(g+k,0,F),S(x)},C=[{field:"label",header:u("devStudio.explorer.name","Name")}];return t.jsxs("div",{className:"nice-development-studio__template","data-testid":"studio-template-editor",children:[t.jsxs("div",{className:"nice-development-studio__doc-bar",children:[t.jsx(h.NiceIcon,{name:"layers",size:14}),t.jsx("strong",{className:"nice-development-studio__doc-title",children:i?((w=l.translations.en)==null?void 0:w.name)||l.id:u("devStudio.template.new","New template")}),t.jsx("span",{className:"nice-development-studio__spacer"}),!p&&t.jsx(h.NiceButton,{size:"sm",variant:"primary",disabled:!l.id.trim(),onClick:async()=>{c(null);const g=await e.saveTemplate({...l,id:l.id.trim()},i==null?void 0:i.id);g?s==null||s(g):c(u("devStudio.template.saveFailed","The template could not be saved; see the output panel."))},children:u("devStudio.save","Save")}),!p&&i&&t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:t.jsx(h.NiceIcon,{name:"trash",size:14}),onClick:async()=>{await e.deleteTemplate(i.id)&&(d==null||d())},children:u("devStudio.delete","Delete")})]}),r&&t.jsx("p",{className:"nice-development-studio__error",role:"alert",children:r}),t.jsxs("div",{className:"nice-development-studio__columns",children:[t.jsxs("section",{children:[t.jsx("h4",{children:u("devStudio.template.basics","Template")}),t.jsx(_e,{schema:Li(u),value:b,readOnly:p,onChange:g=>m({...l,id:String(g.id??""),category:g.category||void 0,subCategory:g.subCategory||void 0,parentId:g.parentId||void 0,icon:g.icon||void 0,sortOrder:typeof g.sortOrder=="number"?g.sortOrder:void 0,tags:Array.isArray(g.tags)?g.tags:void 0})}),o&&t.jsx(_e,{schema:o,value:l.extra??{},readOnly:p,onChange:g=>m({...l,extra:g})}),t.jsx("h4",{children:u("devStudio.template.translations","Name and description")}),t.jsx(st,{value:f,locales:[...new Set([...n,...Object.keys(f)])],allowEditLocales:!0,readOnly:p,onChange:g=>m({...l,translations:Object.fromEntries(Object.entries(g).map(([k,x])=>[k,{name:x.name??"",...x.description?{description:x.description}:{}}]))})})]}),t.jsxs("section",{children:[t.jsx("h4",{children:u("devStudio.template.modules","Modules")}),t.jsx(h.NiceTreeGrid,{data:v,nested:!0,keyField:"id",childrenField:"children",columns:C,sortable:!1,compact:!0,checkable:!0,checkStrategy:"leaves",isRowCheckable:g=>g.kind!=="workspace",isRowDisabled:()=>p,checkedKeys:l.modules.map(g=>`m:${g.moduleId}`),onCheckedChange:g=>{const k=g.filter(L=>L.startsWith("m:")).map(L=>L.slice(2)),x=l.modules.filter(L=>k.includes(L.moduleId)),F=k.filter(L=>!x.some(K=>K.moduleId===L)).map(L=>({moduleId:L}));S([...x,...F])},checkedSummary:g=>u("devStudio.template.summary","{count} modules · {required} required").replace("{count}",String(g.checked)).replace("{required}",String(l.modules.filter(k=>k.required).length)),searchable:!0,searchFields:["label"],virtualScroll:!0,height:320,"aria-label":u("devStudio.template.modules","Modules")}),t.jsxs("table",{className:"nice-development-studio__table",children:[t.jsx("thead",{children:t.jsxs("tr",{children:[t.jsx("th",{children:u("devStudio.template.module","Module")}),t.jsx("th",{children:u("devStudio.template.required","required")}),t.jsx("th",{children:u("devStudio.template.condition","Condition")}),!p&&t.jsx("th",{"aria-label":u("devStudio.template.order","Order")})]})}),t.jsx("tbody",{children:l.modules.map((g,k)=>t.jsxs("tr",{children:[t.jsx("td",{children:y.get(g.moduleId)??g.moduleId}),t.jsx("td",{children:t.jsx("input",{type:"checkbox",checked:!!g.required,disabled:p,"aria-label":`${u("devStudio.template.required","required")} ${g.moduleId}`,onChange:x=>S(l.modules.map((F,L)=>L===k?{...F,required:x.target.checked}:F))})}),t.jsx("td",{children:t.jsx("input",{className:"nice-development-studio__cell",value:g.condition??"",readOnly:p,"aria-label":`${u("devStudio.template.condition","Condition")} ${g.moduleId}`,onChange:x=>S(l.modules.map((F,L)=>L===k?{...F,condition:x.target.value||void 0}:F))})}),!p&&t.jsxs("td",{className:"nice-development-studio__nowrap",children:[t.jsx(h.NiceButton,{size:"sm",variant:"ghost",disabled:k===0,ariaLabel:u("devStudio.template.up","Move up"),onClick:()=>N(k,-1),children:t.jsx(h.NiceIcon,{name:"chevron-up",size:12})}),t.jsx(h.NiceButton,{size:"sm",variant:"ghost",disabled:k===l.modules.length-1,ariaLabel:u("devStudio.template.down","Move down"),onClick:()=>N(k,1),children:t.jsx(h.NiceIcon,{name:"chevron-down",size:12})})]})]},g.moduleId))})]})]})]})]})}function qi({session:e,pkg:i,readOnly:n,onNewModule:o,onOpenModule:a}){const{t:s}=h.useNiceTranslation(),[d,u]=j.useState({id:i.id,label:i.label,description:i.description,icon:i.icon}),l=(e.modulesByWs[i.workspaceId]??[]).filter(r=>r.packageId===i.id),m=!n&&!i.derived&&!i.readOnly;return t.jsxs("div",{className:"nice-development-studio__template","data-testid":"studio-package-editor",children:[t.jsxs("div",{className:"nice-development-studio__doc-bar",children:[t.jsx(h.NiceIcon,{name:"archive",size:14}),t.jsx("strong",{className:"nice-development-studio__doc-title",children:i.label||i.id}),t.jsx("span",{className:"nice-development-studio__spacer"}),!n&&t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:t.jsx(h.NiceIcon,{name:"plus",size:14}),onClick:o,children:s("devStudio.package.newModule","New module here")}),m&&t.jsx(h.NiceButton,{size:"sm",variant:"primary",onClick:()=>void e.savePackage({...i,id:String(d.id??i.id),label:String(d.label??""),description:d.description||void 0,icon:d.icon||void 0}),children:s("devStudio.save","Save")})]}),i.derived?t.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.")}):t.jsx(_e,{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:d,readOnly:!m,onChange:r=>u(r)}),t.jsx("h4",{children:s("devStudio.template.modules","Modules")}),t.jsxs("ul",{className:"nice-development-studio__list",children:[l.map(r=>t.jsxs("li",{children:[t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:t.jsx(h.NiceIcon,{name:"box",size:14}),onClick:()=>a(r.id),children:r.label}),r.description&&t.jsx("span",{className:"nice-development-studio__muted",children:r.description})]},r.id)),l.length===0&&t.jsx("li",{className:"nice-development-studio__muted",children:s("devStudio.explorer.empty","No modules.")})]})]})}const Vi=e=>"module"in e?e.module:void 0;function Wi(e){const{screen:i,crumbs:n,session:o,readOnly:a,tutorialButton:s,onBack:d,onSave:u}=e,{t:l}=h.useNiceTranslation(),m=Vi(i),r=m?o.modules[Q(m)]:void 0,c=a(m),p=Ji(i,r,o);return t.jsxs("div",{className:"nice-development-studio__edit","data-testid":"studio-edit-screen",children:[t.jsxs("header",{className:"nice-development-studio__edit-header",children:[t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:t.jsx(h.NiceIcon,{name:"arrow-left",size:14}),onClick:d,"data-testid":"studio-back",children:l("devStudio.edit.back","Back")}),t.jsx(h.NiceBreadcrumb,{className:"nice-development-studio__crumbs",size:"sm",separator:"›",items:n}),t.jsx("span",{className:"nice-development-studio__spacer"}),p&&!c&&t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:t.jsx(h.NiceIcon,{name:"trash",size:14}),onClick:()=>{p(),d()},children:l("devStudio.delete","Delete")}),r&&t.jsxs(t.Fragment,{children:[t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:t.jsx(h.NiceIcon,{name:"check",size:14}),onClick:()=>void o.validate(r.key),children:l("devStudio.validate","Validate")}),!c&&t.jsxs(t.Fragment,{children:[t.jsx(h.NiceButton,{size:"sm",variant:"ghost",disabled:!r.dirty,onClick:()=>o.discard(r.key),children:l("devStudio.discard","Discard changes")}),t.jsx(h.NiceButton,{size:"sm",variant:"primary",disabled:!r.dirty,onClick:()=>u(r.key),"data-tour":"devstudio-save",children:r.dirty?l("devStudio.saveCount","Save ({count})").replace("{count}",String(r.changes.length)):l("devStudio.save","Save")})]})]}),s]}),t.jsx("div",{className:"nice-development-studio__edit-body",children:t.jsx(Gi,{...e,module:r,readOnlyHere:c})})]})}function Ji(e,i,n){if(!i||e.kind!=="entity"&&e.kind!=="item")return;const o=me(i,e.docKey);if(!o)return;if(e.kind==="entity"){const s=oe(i,o);return Array.isArray(s)?()=>n.setDraft(i.key,o.key,rt(s,e.index,null)):void 0}if(e.group==="dataSources"){const s=oe(i,o)??[];return()=>n.setDraft(i.key,o.key,s.filter(d=>d.key!==e.itemKey))}const a=pe(i,o);return()=>n.setDraft(i.key,o.key,Ot(a,e.itemKey,null))}function he(){const{t:e}=h.useNiceTranslation();return t.jsx("p",{className:"nice-development-studio__muted",children:e("devStudio.edit.gone","This is no longer in the module.")})}function Gi(e){var r,c,p,b,f;const{screen:i,module:n,session:o,preset:a,provider:s,locales:d,advanced:u,readOnlyHere:l}=e,{t:m}=h.useNiceTranslation();if(i.kind==="package")return t.jsx(qi,{session:o,pkg:i.pkg,readOnly:e.readOnly(),onNewModule:()=>e.onNewModule({workspaceId:i.pkg.workspaceId,packageId:i.pkg.id}),onOpenModule:v=>e.onReveal({kind:"module",module:{workspaceId:i.pkg.workspaceId,id:v}})});if(i.kind==="template"){const v=i.templateId?(r=o.templates)==null?void 0:r.find(y=>y.id===i.templateId):void 0;return t.jsx(Ai,{session:o,template:v,locales:d,extraSchema:a.templateSchema,readOnly:e.readOnly(),onSaved:y=>{y.id!==i.templateId&&e.onScreen({kind:"template",templateId:y.id})},onDeleted:e.onBack},i.templateId??"new")}if(!n)return t.jsx("p",{className:"nice-development-studio__muted",children:m("devStudio.loading","Loading…")});switch(i.kind){case"manifest":{const v=n.documents.find(y=>y.kind.editor==="manifest");return v?t.jsx(jt,{module:n,doc:v,preset:a,session:o,locales:d,readOnly:l,advanced:u,scriptRunner:e.scriptRunner}):t.jsx(he,{})}case"entity":{const v=me(n,i.docKey),y=v?oe(n,v):void 0,S=Array.isArray(y)?y[i.index]:void 0;return!v||!y||!S?t.jsx(he,{}):t.jsx(it,{value:S,onChange:N=>o.setDraft(n.key,v.key,rt(y,i.index,N)),entityMetaSchema:(c=a.entities)==null?void 0:c.entityMetaSchema,fieldSchema:(p=a.entities)==null?void 0:p.fieldSchema,fieldsKey:(b=a.entities)==null?void 0:b.fieldsKey,readOnly:l,"data-testid":"studio-entity-form"})}case"item":return t.jsx(Ui,{...e,screen:i,module:n});case"document":{const v=me(n,i.docKey);return v?t.jsx(jt,{module:n,doc:v,preset:a,session:o,locales:d,readOnly:l,advanced:u,scriptRunner:e.scriptRunner}):t.jsx(he,{})}case"panel":{const v=(f=e.modulePanels)==null?void 0:f.call(e,{module:n.key,files:n.working,dirty:n.dirty}).find(y=>y.key===i.panelKey);return v?t.jsx(t.Fragment,{children:v.content}):t.jsx(he,{})}case"file":return n.working.some(v=>v.path===i.path)?t.jsx(Ri,{module:n,path:i.path,session:o,readOnly:l}):t.jsx(he,{});case"problems":return t.jsx(Hi,{module:n,issues:e.issues(n.key),onReveal:e.onReveal});case"history":return t.jsx(Yi,{module:n,provider:s,session:o,readOnly:l})}}function Ui({screen:e,module:i,session:n,readOnlyHere:o,advanced:a,renderViewPreview:s,onScreen:d}){const{t:u}=h.useNiceTranslation(),l=me(i,e.docKey);if(!l)return t.jsx(he,{});if(e.group==="dataSources"){const f=oe(i,l)??[],v=f.find(y=>y.key===e.itemKey);return v?t.jsx(h.NiceDataSourceBuilder,{value:v,schemas:T.entitiesToSchemas(Ye(i)),onChange:y=>{n.setDraft(i.key,l.key,f.map(S=>S.key===v.key?y:S)),y.key!==v.key&&d({...e,itemKey:y.key})}}):t.jsx(he,{})}const m=pe(i,l),r=m.find(f=>f.key===e.itemKey);if(!r)return t.jsx(he,{});const c=f=>{n.setDraft(i.key,l.key,Ot(m,r.key,f)),f.key!==r.key&&d({...e,itemKey:f.key})},p=f=>c({...r,definition:f,label:f.name||r.label,key:f.id&&!m.some(v=>v!==r&&v.key===f.id)?f.id:r.key});if(r.definition===void 0)return a?t.jsxs("div",{className:"nice-development-studio__source",children:[t.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})`:""]}),t.jsx(nt,{value:r.source,readOnly:o,label:r.label,height:"100%",onChange:f=>c({...r,source:f})})]}):t.jsx("p",{className:"nice-development-studio__muted",children:u("devStudio.preview.noDesigner","There is no designer for this kind of entry yet.")});if(e.group==="workflows")return t.jsx(Ut.NiceWorkflowDesigner,{workflow:r.definition,onChange:f=>p(f),readOnly:o});const b=t.jsx(h.NiceViewEditor,{value:r.definition,onChange:f=>p(f),entities:Ye(i),dataSourceOptions:i.documents.filter(f=>f.kind.editor==="dataSources").flatMap(f=>oe(i,f)??[]).map(f=>({key:f.key,label:f.label})),height:640});return s?t.jsx(h.NiceTabs,{tabs:[{id:"design",label:u("devStudio.view.design","Design"),content:b},{id:"preview",label:u("devStudio.view.hostPreview","Preview in the app"),content:s({module:i.key,item:r,files:i.working})}]}):b}function Hi({module:e,issues:i,onReveal:n}){const{t:o}=h.useNiceTranslation();return i.length===0?t.jsx("p",{className:"nice-development-studio__muted",children:o("devStudio.overview.noProblems","No problems found.")}):t.jsx("ul",{className:"nice-development-studio__issues","data-testid":"studio-problems",children:i.map((a,s)=>t.jsxs("li",{className:`nice-development-studio__issue nice-development-studio__issue--${a.severity}`,children:[t.jsx(h.NiceIcon,{name:a.severity==="error"?"error":a.severity==="warning"?"warning":"info",size:14}),t.jsx("span",{children:Pt(o,a)}),a.path&&t.jsx("span",{className:"nice-development-studio__muted",children:a.path}),t.jsx(h.NiceButton,{size:"sm",variant:"ghost",onClick:()=>n(zt(e,a)),children:o("devStudio.problems.goTo","Go to")})]},s))})}function Pt(e,i){return i.messageKey?Object.entries(i.params??{}).reduce((n,[o,a])=>n.replace(`{${o}}`,String(a)),e(i.messageKey,i.message)):i.message}function Yi({module:e,provider:i,session:n,readOnly:o}){const[a,s]=j.useState(null),d=e.key;return j.useEffect(()=>{let u=!0;return i!=null&&i.listRevisions&&i.listRevisions(d).then(l=>{u&&s(l.map(m=>({id:m.id,label:m.label,author:m.author,timestamp:m.timestamp,summary:m.summary})))}).catch(()=>s([])),()=>{u=!1}},[i,d,e.files]),t.jsx(h.NiceRevisionHistory,{revisions:a??[],language:"json",loadContent:i!=null&&i.readRevision?u=>i.readRevision(d,u):void 0,onRollback:i!=null&&i.rollback&&!o?async u=>{await i.rollback(d,u),await n.reload(d)}:void 0})}function Xi({prompt:e,onClose:i}){const{t:n}=h.useNiceTranslation(),[o,a]=j.useState(e.initial),s=()=>{o.trim()&&(i(),e.onSubmit(o.trim()))};return t.jsx(h.NiceModal,{open:!0,onClose:i,title:e.title,footer:t.jsxs(t.Fragment,{children:[t.jsx(h.NiceButton,{variant:"ghost",onClick:i,children:n("devStudio.cancel","Cancel")}),t.jsx(h.NiceButton,{variant:"primary",disabled:!o.trim(),onClick:s,children:n("devStudio.ok","OK")})]}),children:t.jsx("div",{className:"nice-development-studio__form",children:t.jsx(h.NiceTextInput,{label:n("devStudio.package.label","Name"),value:o,onChange:a,onKeyDown:d=>{d.key==="Enter"&&s()},"data-testid":"studio-layout-name"})})})}function Zi(e,i){const{t:n}=h.useNiceTranslation(),[o,a]=j.useState(null),s=j.useCallback((u,l)=>{var b;const m=e.modules[Q(u)];if(!m)return;const r=T.studioLayoutPath(m.working),c=(b=m.working.find(f=>f.path===r))==null?void 0:b.text,p=l(T.parseStudioLayout(c));if(T.isEmptyStudioLayout(p)){c!==void 0&&e.deleteFile(u,r);return}e.setRaw(u,r,T.serializeStudioLayout(p,c))},[e]);return{menuFor:j.useCallback(u=>{const l=u.node,m=Ee(l),r=m?e.modules[Q(m)]:void 0;if(!m||!r||i(m))return;const c=Bt(r),p=(S,N,C)=>a({title:S,initial:N,onSubmit:C}),b=n("devStudio.layout.newFolder","New folder"),f=(S,N,C)=>({id:"new-folder",icon:"folder",label:b,onSelect:()=>p(b,"",w=>s(m,g=>T.addStudioFolder(g,{label:w,group:S,parent:N,section:C}).layout))}),v=[];switch(l.kind){case"module":v.push({id:"new-section",icon:"layers",label:n("devStudio.layout.newSection","New section"),onSelect:()=>p(n("devStudio.layout.newSection","New section"),"",S=>s(m,N=>T.addStudioSection(N,S).layout))});break;case"group":l.group!=="files"&&v.push(f(l.group,void 0,l.section));break;case"section":v.push({id:"rename",icon:"edit",label:n("devStudio.layout.renameSection","Rename section"),onSelect:()=>p(n("devStudio.layout.renameSection","Rename section"),u.label,S=>s(m,N=>T.renameStudioLayoutNode(N,{kind:"section",id:l.sectionId},S)))},{id:"delete",icon:"trash",danger:!0,label:n("devStudio.layout.deleteSection","Delete section"),onSelect:()=>s(m,S=>T.removeStudioLayoutNode(S,{kind:"section",id:l.sectionId}))});break;case"folder":{const S=c.folders.find(N=>N.id===l.folderId);v.push(f(l.group,l.folderId,S==null?void 0:S.section),{id:"rename",icon:"edit",label:n("devStudio.layout.renameFolder","Rename folder"),onSelect:()=>p(n("devStudio.layout.renameFolder","Rename folder"),u.label,N=>s(m,C=>T.renameStudioLayoutNode(C,{kind:"folder",id:l.folderId},N)))},{id:"delete",icon:"trash",danger:!0,label:n("devStudio.layout.deleteFolder","Delete folder"),onSelect:()=>s(m,N=>T.removeStudioLayoutNode(N,{kind:"folder",id:l.folderId}))});break}}const y=u.ref;if(y){const S=y.slice(0,y.indexOf(":")),N=c.placement[y],C=[{id:"move-new-folder",icon:"folder",label:n("devStudio.layout.moveToNewFolder","Move to a new folder…"),onSelect:()=>p(b,"",w=>s(m,g=>{const k=T.addStudioFolder(g,{label:w,group:S,section:N==null?void 0:N.section});return T.placeStudioEntry(k.layout,y,{folder:k.id})}))},...c.folders.filter(w=>w.group===S&&w.id!==(N==null?void 0:N.folder)).map(w=>({id:`move-folder-${w.id}`,icon:"folder",label:n("devStudio.layout.moveToFolder","Move to folder: {name}").replace("{name}",w.label),onSelect:()=>s(m,g=>T.placeStudioEntry(g,y,{folder:w.id}))})),...c.sections.filter(w=>w.id!==(N==null?void 0:N.section)||!!(N!=null&&N.folder)).map(w=>({id:`move-section-${w.id}`,icon:"layers",label:n("devStudio.layout.moveToSection","Move to section: {name}").replace("{name}",w.label),onSelect:()=>s(m,g=>T.placeStudioEntry(g,y,{section:w.id}))}))];(N!=null&&N.folder||N!=null&&N.section)&&C.push({id:"move-back",icon:"arrow-left",label:n("devStudio.layout.moveBack","Move back to its group"),onSelect:()=>s(m,w=>T.placeStudioEntry(w,y,{}))}),v.length&&v.push({id:"divider",divider:!0}),v.push(...C)}return v.length?v:void 0},[e.modules,i,s,n]),dialog:o?t.jsx(Xi,{prompt:o,onClose:()=>a(null)}):null}}function se({icon:e,title:i,subtitle:n,badges:o,actions:a,children:s}){return t.jsxs("section",{className:"nice-development-studio__preview","data-testid":"studio-preview",children:[t.jsxs("div",{className:"nice-development-studio__preview-info",children:[t.jsxs("header",{className:"nice-development-studio__preview-head",children:[t.jsx(h.NiceIcon,{name:e,size:20}),t.jsxs("div",{className:"nice-development-studio__preview-name",children:[t.jsx("h3",{className:"nice-development-studio__preview-title",children:i}),n&&t.jsx("span",{className:"nice-development-studio__muted",children:n})]})]}),o&&t.jsx("div",{className:"nice-development-studio__preview-badges",children:o}),s]}),a&&t.jsx("footer",{className:"nice-development-studio__preview-actions",children:a})]})}function de({items:e}){const i=e.filter(([,n])=>n!=null&&n!=="");return i.length===0?null:t.jsx("dl",{className:"nice-development-studio__facts",children:i.map(([n,o])=>t.jsxs("div",{className:"nice-development-studio__fact",children:[t.jsx("dt",{children:n}),t.jsx("dd",{children:o})]},n))})}function ke({rows:e,onSelect:i,limit:n=12}){const{t:o}=h.useNiceTranslation();return e.length===0?null:t.jsxs("ul",{className:"nice-development-studio__preview-list",children:[e.slice(0,n).map(a=>t.jsxs("li",{children:[t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:t.jsx(h.NiceIcon,{name:a.icon,size:14}),onClick:()=>i(a.id),children:a.label}),a.info&&t.jsx("span",{className:"nice-development-studio__muted",children:a.info})]},a.id)),e.length>n&&t.jsx("li",{className:"nice-development-studio__muted",children:o("devStudio.preview.more","…and {count} more").replace("{count}",String(e.length-n))})]})}const Me=e=>Array.isArray(e)?e.length:void 0;function Qi(e){var c,p,b,f;const{row:i,session:n,advanced:o,onEdit:a}=e,{t:s}=h.useNiceTranslation();if(!i)return t.jsx("div",{className:"nice-development-studio__placeholder","data-testid":"studio-preview-empty",children:e.emptyText});const d=i.node,u=d.kind==="package"?Kt(d.workspaceId,n.packagesByWs[d.workspaceId],n.modulesByWs[d.workspaceId]??[]):void 0,l=Fi(d,{modules:n.modules,packages:u,advanced:o}),m=l?t.jsx(h.NiceButton,{size:"sm",variant:"primary",leftIcon:t.jsx(h.NiceIcon,{name:"edit",size:14}),onClick:()=>a(l),"data-testid":"studio-edit","data-tour":"devstudio-edit",children:d.kind==="module"?s("devStudio.preview.editSettings","Edit settings"):s("devStudio.preview.edit","Edit")}):null,r="module"in d?n.modules[Q(d.module)]:void 0;if("module"in d&&!r)return t.jsx(se,{icon:i.icon,title:i.label,children:t.jsx("p",{className:"nice-development-studio__muted",children:s("devStudio.loading","Loading…")})});switch(d.kind){case"workspace":return t.jsx(en,{...e,row:i,workspaceId:d.workspaceId});case"package":return t.jsx(tn,{...e,row:i,workspaceId:d.workspaceId,packageId:d.packageId,editButton:m});case"module":return t.jsx(nn,{...e,row:i,module:r,editButton:m});case"group":return t.jsx(sn,{...e,row:i,module:r,group:d.group});case"entity":return t.jsx(dn,{...e,row:i,module:r,docKey:d.docKey,index:d.index,editButton:m});case"item":return t.jsx(rn,{...e,row:i,module:r,node:d,editButton:m});case"document":return t.jsx(ln,{...e,row:i,module:r,docKey:d.docKey,editButton:m});case"section":case"folder":return t.jsx(se,{icon:i.icon,title:i.label,children:t.jsx(ke,{rows:i.children??[],onSelect:e.onSelect})});case"panel":return t.jsx(se,{icon:i.icon,title:i.label,actions:m});case"file":{const v=r.working.find(y=>y.path===d.path);return t.jsx(se,{icon:"file",title:i.label,actions:m,children:t.jsx(de,{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 t.jsx(se,{icon:"layers",title:i.label,actions:(c=e.provider)!=null&&c.saveTemplate&&!e.readOnly()?t.jsx(h.NiceButton,{size:"sm",variant:"primary",leftIcon:t.jsx(h.NiceIcon,{name:"plus",size:14}),onClick:e.onNewTemplate,children:s("devStudio.preview.newTemplate","New template")}):void 0,children:t.jsx(ke,{rows:i.children??[],onSelect:e.onSelect})});case"category":return t.jsx(se,{icon:"folder",title:i.label,children:t.jsx(ke,{rows:i.children??[],onSelect:e.onSelect})});case"template":{const v=(p=n.templates)==null?void 0:p.find(S=>S.id===d.templateId),y=(v==null?void 0:v.translations.en)??Object.values((v==null?void 0:v.translations)??{})[0];return t.jsxs(se,{icon:i.icon,title:i.label,subtitle:v==null?void 0:v.category,actions:m,children:[(y==null?void 0:y.description)&&t.jsx("p",{children:y.description}),t.jsx(de,{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"),(b=v==null?void 0:v.tags)==null?void 0:b.join(", ")]]}),t.jsx(ke,{rows:i.children??[],onSelect:e.onSelect,limit:8})]})}case"templateModule":{const v=(f=n.templates)==null?void 0:f.find(S=>S.id===d.templateId),y=v==null?void 0:v.modules.find(S=>S.moduleId===d.moduleId);return t.jsxs(se,{icon:"box",title:i.label,subtitle:d.moduleId,actions:d.target?t.jsx(h.NiceButton,{size:"sm",variant:"primary",leftIcon:t.jsx(h.NiceIcon,{name:"arrow-right",size:14}),onClick:()=>e.onReveal({kind:"module",module:d.target}),children:s("devStudio.preview.goToModule","Go to the module")}):void 0,children:[t.jsx(de,{items:[[s("devStudio.preview.required","Required"),y!=null&&y.required?s("devStudio.preview.yes","yes"):void 0],[s("devStudio.preview.condition","Condition"),y==null?void 0:y.condition],[s("devStudio.preview.description","Description"),y==null?void 0:y.description]]}),i.missing&&t.jsx("p",{className:"nice-development-studio__error",children:s("devStudio.preview.missingModule","No project has this module.")})]})}}}function en({row:e,workspaceId:i,session:n,provider:o,readOnly:a,canCreateModule:s,onSelect:d,onNewModule:u,onNewPackage:l}){var p;const{t:m}=h.useNiceTranslation(),r=n.workspaces.find(b=>b.id===i),c=!a()&&!(r!=null&&r.readOnly);return t.jsxs(se,{icon:e.icon,title:e.label,badges:r!=null&&r.readOnly?t.jsx("span",{className:"nice-development-studio__tag",children:m("devStudio.explorer.readOnly","Read-only")}):void 0,actions:c&&(s||o!=null&&o.savePackage)?t.jsxs(t.Fragment,{children:[s&&t.jsx(h.NiceButton,{size:"sm",variant:"primary",leftIcon:t.jsx(h.NiceIcon,{name:"box",size:14}),onClick:()=>u({workspaceId:i}),children:m("devStudio.preview.newModule","New module")}),(o==null?void 0:o.savePackage)&&t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:t.jsx(h.NiceIcon,{name:"archive",size:14}),onClick:()=>l(i),children:m("devStudio.preview.newPackage","New package")})]}):void 0,children:[(r==null?void 0:r.description)&&t.jsx("p",{children:r.description}),t.jsx(de,{items:[[m("devStudio.preview.packages","Packages"),String(((p=e.children)==null?void 0:p.length)??0)],[m("devStudio.preview.modules","Modules"),e.info]]}),t.jsx(ke,{rows:e.children??[],onSelect:d})]})}function tn({row:e,workspaceId:i,packageId:n,session:o,readOnly:a,canCreateModule:s,editButton:d,onSelect:u,onNewModule:l}){var b;const{t:m}=h.useNiceTranslation(),r=(b=o.packagesByWs[i])==null?void 0:b.find(f=>f.id===n),c=o.workspaces.find(f=>f.id===i),p=!a()&&!(c!=null&&c.readOnly);return t.jsxs(se,{icon:e.icon,title:e.label,subtitle:n,actions:t.jsxs(t.Fragment,{children:[d,p&&s&&t.jsx(h.NiceButton,{size:"sm",variant:d?"ghost":"primary",leftIcon:t.jsx(h.NiceIcon,{name:"plus",size:14}),onClick:()=>l({workspaceId:i,packageId:n}),children:m("devStudio.preview.newModuleHere","New module here")})]}),children:[(r==null?void 0:r.description)&&t.jsx("p",{children:r.description}),t.jsx(ke,{rows:e.children??[],onSelect:u})]})}function nn(e){var g;const{row:i,module:n,session:o,preset:a,provider:s,readOnly:d,editButton:u}=e,{t:l}=h.useNiceTranslation(),m=n.key,r=(g=o.modulesByWs[m.workspaceId])==null?void 0:g.find(k=>k.id===m.id),c=d(m),p=e.issues(m),b=(r==null?void 0:r.contents)==="manifest"&&t.jsx("span",{title:l("devStudio.preview.manifestOnly","This provider gives only the manifest"),children:"—"}),f=at(n).length,v=n.documents.filter(k=>k.kind.editor==="views").reduce((k,x)=>k+pe(n,x).length,0),y=new Set(n.documents.filter(k=>k.kind.editor==="i18n").flatMap(k=>Object.keys(oe(n,k)??{}))),S={key:m,files:n.working,documents:n.documents},N=a.newFile?a.kinds.map(k=>{var x;return{kind:k,file:(x=a.newFile)==null?void 0:x.call(a,k.id,S)}}).filter(k=>!!k.file&&!n.working.some(x=>x.path===k.file.path)):[],C=k=>t.jsx(h.NiceIcon,{name:k,size:14}),w=[...s!=null&&s.listRevisions?[{id:"history",icon:C("clock"),label:l("devStudio.overview.history","History"),onClick:()=>e.onEdit({kind:"history",module:m})}]:[],...e.canDuplicateModule&&!d()?[{id:"duplicate",icon:C("copy"),label:l("devStudio.explorer.duplicate","Duplicate"),onClick:()=>e.onModuleAction("duplicate",m)}]:[],...s!=null&&s.saveTemplate&&o.templates&&!d()?[{id:"addToTemplate",icon:C("layers"),label:l("devStudio.explorer.addToTemplate","Add to template"),onClick:()=>e.onModuleAction("addToTemplate",m)}]:[],...c?[]:N.map(({kind:k,file:x})=>({id:`add:${k.id}`,icon:C(k.icon??"plus"),label:`${l("devStudio.preview.add","Add:")} ${k.labelKey?l(k.labelKey,k.label):k.label}`,onClick:()=>o.setRaw(m,x.path,x.text)})),...s!=null&&s.deleteModule&&!c?[{id:"sep",divider:!0},{id:"delete",icon:C("trash"),label:l("devStudio.delete","Delete"),danger:!0,onClick:()=>e.onModuleAction("delete",m)}]:[]];return t.jsxs(se,{icon:i.icon,title:i.label,subtitle:(r==null?void 0:r.location)??m.id,badges:t.jsxs(t.Fragment,{children:[(r==null?void 0:r.readOnly)&&t.jsx("span",{className:"nice-development-studio__tag",children:l("devStudio.explorer.readOnly","Read-only")}),(r==null?void 0:r.shadowedBy)&&t.jsx("span",{className:"nice-development-studio__tag",title:r.shadowedBy,children:l("devStudio.explorer.shadowed","shadowed")})]}),actions:t.jsxs(t.Fragment,{children:[u,n.dirty&&!c&&t.jsxs(t.Fragment,{children:[t.jsx(h.NiceButton,{size:"sm",variant:"primary",leftIcon:C("save"),onClick:()=>e.onSave(m),"data-tour":"devstudio-save",children:l("devStudio.saveCount","Save ({count})").replace("{count}",String(n.changes.length))}),t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:C("undo"),onClick:()=>o.discard(m),children:l("devStudio.discard","Discard changes")})]}),t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:C("check"),onClick:()=>void o.validate(m),children:l("devStudio.validate","Validate")}),t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:C(p.length===0?"success":"warning"),onClick:()=>e.onEdit({kind:"problems",module:m}),children:`${l("devStudio.overview.problems","Problems")} (${p.length})`}),w.length>0&&t.jsx(h.NiceMenu,{className:"nice-development-studio__more",variant:"ghost",size:"sm",fullWidth:!0,items:[{id:"more",icon:C("more-horizontal"),label:l("devStudio.preview.more.actions","More actions"),children:w}]})]}),children:[(r==null?void 0:r.description)&&t.jsx("p",{children:r.description}),t.jsx(de,{items:[["Id",m.id],[l("devStudio.preview.version","Version"),r==null?void 0:r.version],[l("devStudio.preview.entities","Entities"),b||String(f)],[l("devStudio.preview.views","Views"),b||String(v)],[l("devStudio.preview.languages","Languages"),b||[...y].join(", ")],[l("devStudio.preview.state","State"),n.dirty?l("devStudio.status.changed","{count} changed files").replace("{count}",String(n.changes.length)):void 0]]}),p.length>0&&t.jsxs("div",{className:"nice-development-studio__preview-issues",children:[t.jsx("ul",{className:"nice-development-studio__issues",children:p.slice(0,3).map((k,x)=>t.jsx("li",{className:`nice-development-studio__issue nice-development-studio__issue--${k.severity}`,children:t.jsxs("button",{type:"button",className:"nice-development-studio__issue-link",title:l("devStudio.problems.goTo","Go to"),onClick:()=>e.onReveal(zt(n,k)),children:[t.jsx(h.NiceIcon,{name:k.severity==="error"?"error":k.severity==="warning"?"warning":"info",size:14}),t.jsx("span",{children:Pt(l,k)})]})},x))}),p.length>3&&t.jsx("span",{className:"nice-development-studio__muted",children:l("devStudio.preview.more","…and {count} more").replace("{count}",String(p.length-3))})]})]})}function sn({row:e,module:i,group:n,preset:o,session:a,readOnly:s,onSelect:d,onEdit:u}){const{t:l}=h.useNiceTranslation(),r=s(i.key)?void 0:on(n,i,o,a);return t.jsx(se,{icon:e.icon,title:e.label,actions:r?t.jsx(h.NiceButton,{size:"sm",variant:"primary",leftIcon:t.jsx(h.NiceIcon,{name:"plus",size:14}),onClick:()=>u(r.run()),"data-testid":"studio-add",children:r.label(l)}):void 0,children:t.jsx(ke,{rows:e.children??[],onSelect:d})})}function on(e,i,n,o){var r,c;const a=e==="entities"?"entities":e==="views"?"views":e==="workflows"?"workflows":e==="dataSources"?"dataSources":void 0,s=a?i.documents.find(p=>p.kind.editor===a&&p.model!==void 0):void 0;if(!s)return;const d=i.key;if(e==="entities"){const p=oe(i,s)??[],b=((r=n.entities)==null?void 0:r.nameKey)??"name",f=((c=n.entities)==null?void 0:c.fieldsKey)??"fields";return{label:v=>v("devStudio.preview.newEntity","New entity"),run:()=>(o.setDraft(d,s.key,[...p,{[b]:`Entity${p.length+1}`,[f]:[]}]),{kind:"entity",module:d,docKey:s.key,index:p.length})}}if(e==="dataSources"){const p=oe(i,s)??[];return{label:b=>b("devStudio.items.addDataSource","New data source"),run:()=>{const b={key:`source${p.length+1}`,kind:"query",query:{tables:[],joins:[],conditions:[],sorts:[],groupBy:[],distinct:!1},sql:""};return o.setDraft(d,s.key,[...p,b]),{kind:"item",module:d,group:"dataSources",docKey:s.key,itemKey:b.key}}}}const u=pe(i,s),l=u.length+1,m=e==="views"?{id:`view-${l}`,name:`View ${l}`,version:2,columns:12,rows:[],dataSources:[]}:{id:`workflow-${l}`,name:`Workflow ${l}`,entityType:"",version:1,states:[],transitions:[]};return{label:p=>e==="views"?p("devStudio.items.addView","New view"):p("devStudio.items.addWorkflow","New workflow"),run:()=>{const p={key:m.id,label:m.name,definition:m,source:m};return o.setDraft(d,s.key,[...u,p]),{kind:"item",module:d,group:e,docKey:s.key,itemKey:m.id}}}}const an=[["isPrimaryKey","PK","Primary key"],["isForeignKey","FK","Foreign key"],["isRequired","Req","Required"]];function dn({row:e,module:i,docKey:n,index:o,preset:a,session:s,readOnly:d,editButton:u,onReveal:l}){var y;const{t:m}=h.useNiceTranslation(),r=me(i,n),c=r?oe(i,r):void 0,p=Array.isArray(c)?c[o]:void 0;if(!r||!c||!p)return t.jsx(se,{icon:"table",title:e.label,children:t.jsx("p",{className:"nice-development-studio__muted",children:m("devStudio.edit.gone","This is no longer in the module.")})});const b=((y=a.entities)==null?void 0:y.fieldsKey)??"fields",f=Array.isArray(p[b])?p[b]:[],v=d(i.key);return t.jsxs(se,{icon:"table",title:dt(p)||e.label,subtitle:String(p.name??""),badges:t.jsxs(t.Fragment,{children:[!!p.isAudited&&t.jsx("span",{className:"nice-development-studio__tag",children:m("entityEditor.flag.audited.abbr","Audit")}),!!p.isSoftDeleteEnabled&&t.jsx("span",{className:"nice-development-studio__tag",children:m("entityEditor.flag.softDelete.abbr","Soft-del")})]}),actions:t.jsxs(t.Fragment,{children:[u,!v&&t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:t.jsx(h.NiceIcon,{name:"trash",size:14}),onClick:()=>{s.setDraft(i.key,r.key,rt(c,o,null)),l({kind:"group",module:i.key,group:"entities"})},children:m("devStudio.delete","Delete")})]}),children:[typeof p.description=="string"&&p.description&&t.jsx("p",{children:p.description}),t.jsx(de,{items:[[m("entityEditor.col.table","Table"),p.tableName],[m("entityEditor.col.fields","Fields"),String(f.length)]]}),f.length>0&&t.jsx("table",{className:"nice-development-studio__table nice-development-studio__preview-fields",children:t.jsx("tbody",{children:f.slice(0,8).map((S,N)=>t.jsxs("tr",{children:[t.jsx("td",{children:String(S.name??"")}),t.jsx("td",{className:"nice-development-studio__muted",children:String(S.dataType??S.type??"")}),t.jsx("td",{children:an.filter(([C])=>S[C]||C==="isRequired"&&S.required).map(([,C,w])=>t.jsx("span",{className:"nice-development-studio__tag",title:w,children:C},C))})]},N))})}),f.length>8&&t.jsx("span",{className:"nice-development-studio__muted",children:m("devStudio.preview.more","…and {count} more").replace("{count}",String(f.length-8))})]})}function rn({row:e,module:i,node:n,advanced:o,renderViewPreview:a,editButton:s}){var p,b,f,v;const{t:d}=h.useNiceTranslation(),u=me(i,n.docKey),l=u?pe(i,u).find(y=>y.key===n.itemKey):void 0;if(!l)return t.jsx(se,{icon:e.icon,title:e.label,children:t.jsx("p",{className:"nice-development-studio__muted",children:d("devStudio.edit.gone","This is no longer in the module.")})});const m=l.source??{},r=l.definition??{},c=n.group==="views"?[["Id",l.key],[d("devStudio.preview.type","Type"),m.viewType??m.type??m.kind],[d("devStudio.preview.entity","Entity"),m.entityName??m.entity],[d("devStudio.preview.columns","Columns"),(p=Me(m.columns))==null?void 0:p.toString()],[d("devStudio.preview.rows","Rows"),(b=Me(r.rows))==null?void 0:b.toString()]]:n.group==="workflows"?[["Id",l.key],[d("devStudio.preview.states","States"),(f=Me(r.states??m.states))==null?void 0:f.toString()],[d("devStudio.preview.transitions","Transitions"),(v=Me(r.transitions??m.transitions))==null?void 0:v.toString()]]:[[d("devStudio.preview.key","Key"),l.key],[d("devStudio.preview.type","Type"),r.kind??void 0]];return t.jsxs(se,{icon:e.icon,title:l.label||l.key,badges:l.definition===void 0?t.jsx("span",{className:"nice-development-studio__tag",children:d("devStudio.tree.noForm","no designer")}):void 0,actions:s,children:[t.jsx(de,{items:c}),l.definition===void 0&&t.jsx("p",{className:"nice-development-studio__muted",children:o?d("devStudio.preview.noDesignerAdvanced","There is no designer for this kind of entry yet; edit its source."):d("devStudio.preview.noDesigner","There is no designer for this kind of entry yet.")}),n.group==="views"&&a&&t.jsx("div",{className:"nice-development-studio__preview-view",children:a({module:i.key,item:l,files:i.working})})]})}function ln({row:e,module:i,docKey:n,advanced:o,editButton:a}){var m;const{t:s}=h.useNiceTranslation(),d=me(i,n);if(!d)return t.jsx(se,{icon:e.icon,title:e.label,children:t.jsx("p",{className:"nice-development-studio__muted",children:s("devStudio.edit.gone","This is no longer in the module.")})});const u=oe(i,d);let l=null;if(d.model===void 0)l=t.jsxs("p",{className:"nice-development-studio__error",role:"alert",children:[o?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.")," ",d.error]});else if(d.kind.editor==="i18n"){const r=u??{},c=Math.max(0,...Object.values(r).map(p=>Object.keys(p??{}).length));l=t.jsx(de,{items:Object.entries(r).map(([p,b])=>{const f=Object.keys(b??{}).length;return[p,f<c?s("devStudio.preview.keysMissing","{count} keys, {missing} missing").replace("{count}",String(f)).replace("{missing}",String(c-f)):s("devStudio.preview.keys","{count} keys").replace("{count}",String(f))]})})}else if(d.kind.editor==="permissions"){const r=u??{permissions:[],groups:[]};l=t.jsx(de,{items:[[s("devStudio.permissions.codes","Permissions"),String(r.permissions.length)],[s("devStudio.permissions.groups","Groups"),String(r.groups.length)]]})}else if(d.kind.editor==="seeds"){const r=u??{seeds:{}};l=t.jsx(de,{items:Object.entries(r.seeds??{}).map(([c,p])=>[c,s("devStudio.preview.rowsCount","{count} rows").replace("{count}",String(p.length))])})}else d.kind.editor==="hooks"?l=t.jsx(de,{items:[[s("devStudio.preview.bindings","Bindings"),(m=Me(u))==null?void 0:m.toString()]]}):d.kind.editor==="script"&&(l=t.jsx(de,{items:[[s("devStudio.preview.lines","Lines"),String(String(u??"").split(`
|
|
6
|
-
`).length)]]}));return t.jsx(se,{icon:e.icon,title:e.label,subtitle:d.paths.join(", "),actions:a,children:l})}function cn({tree:e,selected:i,expanded:n,onExpandedChange:o,onSelect:a,loadModule:s,newItems:d,actions:u,onRefresh:l,tutorialButton:m,emptyText:r,minWidth:c,contextMenuItems:p}){const{t:b}=h.useNiceTranslation(),f=j.useMemo(()=>[{field:"label",header:b("devStudio.explorer.name","Name"),render:(y,S)=>t.jsxs("span",{className:"nice-development-studio__tree-name",style:{maxWidth:`calc(100% - ${(S.depth??0)*20+28}px)`},children:[t.jsx(h.NiceIcon,{name:S.icon,size:14}),t.jsx("span",{className:`nice-development-studio__tree-label${S.missing?" nice-development-studio__missing":""}`,title:S.label,children:S.label}),S.dirty&&t.jsx("span",{className:"nice-development-studio__dot",title:b("devStudio.explorer.unsaved","Unsaved changes"),children:t.jsx(h.NiceIcon,{name:"circle",size:8})}),!!S.issues&&t.jsx("span",{className:"nice-development-studio__badge",title:b("devStudio.explorer.problems","Problems"),children:S.issues}),S.readOnly&&t.jsx("span",{title:b("devStudio.explorer.readOnly","Read-only"),children:t.jsx(h.NiceIcon,{name:"lock",size:12})}),S.noForm&&t.jsx("span",{className:"nice-development-studio__tag",children:b("devStudio.tree.noForm","no designer")}),S.shadowedBy&&t.jsx("span",{className:"nice-development-studio__tag",title:S.shadowedBy,children:b("devStudio.explorer.shadowed","shadowed")}),S.missing&&t.jsx("span",{className:"nice-development-studio__tag",children:b("devStudio.explorer.missing","missing")})]})},{field:"info",header:"",width:56,align:"right"}],[b]),v=t.jsxs("div",{className:"nice-development-studio__tree-actions",children:[d.length>0&&t.jsx(h.NiceMenu,{variant:"ghost",size:"sm",items:[{id:"new",label:b("devStudio.tree.new","New"),icon:t.jsx(h.NiceIcon,{name:"plus",size:14}),children:d}],"data-testid":"studio-new-menu"}),t.jsx(h.NiceButton,{size:"sm",variant:"ghost",ariaLabel:b("devStudio.refresh","Refresh"),onClick:l,children:t.jsx(h.NiceIcon,{name:"refresh",size:14})}),u==null?void 0:u.map(y=>t.jsx(h.NiceButton,{size:"sm",variant:"ghost",disabled:y.disabled,leftIcon:y.icon?t.jsx(h.NiceIcon,{name:y.icon,size:14}):void 0,onClick:y.onSelect,children:y.label},y.key)),m&&t.jsx("span",{className:"nice-development-studio__spacer"}),m]});return t.jsx("div",{className:"nice-development-studio__tree","data-tour":"devstudio-explorer",style:{minWidth:c},children:t.jsx(h.NiceTreeGrid,{data:e.rows,nested:!0,keyField:"id",childrenField:"children",columns:f,sortable:!1,compact:!0,searchable:!0,searchFields:["label","search"],searchPlaceholder:b("devStudio.tree.search","Search modules, entities and views"),toolbar:v,toolbarActions:["collapseAll"],expandedKeys:n,onExpandedChange:o,hasChildren:y=>y.node.kind==="module"&&!y.children,loadChildren:async y=>(y.node.kind==="module"&&await s(y.node.module),[]),onRowClick:a,contextMenuItems:p,rowClassName:y=>y.id===i?"nice-development-studio__tree-row--selected":void 0,emptyText:r,"aria-label":b("devStudio.explorer.modules","Modules"),"data-testid":"studio-tree"})})}const un=[{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"}],mn=["en","pl","de","fr","es","uk"],pn=j.forwardRef(function(i,n){var mt,pt;const{provider:o,preset:a,defaultModule:s,defaultExplorerTab:d="modules",displayMode:u="standard",actions:l,onModuleOpen:m,onSaved:r,onError:c,reviewBeforeSave:p=!0,scriptRunner:b,renderViewPreview:f,modulePanels:v,readOnly:y=!1,height:S=720,explorerWidth:N=320,previewWidth:C=260,tutorial:w,className:g,style:k,id:x,testId:F,"data-testid":L}=i,{t:K}=h.useNiceTranslation(),V=j.useRef(null);j.useImperativeHandle(n,()=>V.current);const G=u==="advanced",Y=j.useMemo(()=>typeof a=="function"?a(K):a??T.nativeStudioPreset,[a,K]),H=j.useMemo(()=>Y.locales??mn,[Y]),$=ji(o,Y,{locales:H,onError:c,t:K}),{openModule:O}=$,[P,A]=j.useState(""),[te,X]=j.useState([]),[D,Z]=j.useState(null),[re,xe]=j.useState(null),[q,I]=j.useState(null),E=j.useCallback(_=>{var B;return(B=$.modulesByWs[_.workspaceId])==null?void 0:B.find(W=>W.id===_.id)},[$.modulesByWs]),M=_=>{var B;return((B=E(_))==null?void 0:B.label)??_.id},z=j.useMemo(()=>{const _={};for(const[B,W]of Object.entries($.modules))_[B]=[...Et(W,Y),...$.serverIssues[B]??[]];return _},[$.modules,$.serverIssues,Y]),R=j.useCallback(_=>z[Q(_)]??[],[z]),U=j.useMemo(()=>Object.fromEntries(Object.entries(z).map(([_,B])=>[_,B.filter(W=>W.severity==="error").length])),[z]),ee=j.useCallback(_=>{var W;if(y)return!0;if(!_)return!1;const B=$.workspaces.find(fe=>fe.id===_.workspaceId);return!!(B!=null&&B.readOnly)||!!((W=E(_))!=null&&W.readOnly)},[y,$.workspaces,E]),J=Zi($,ee),ie=j.useMemo(()=>$i({workspaces:$.workspaces,modulesByWs:$.modulesByWs,packagesByWs:$.packagesByWs,templates:$.templates,modules:$.modules,issueCounts:U,panels:v?_=>v({module:_.key,files:_.working,dirty:_.dirty}):void 0,advanced:G,groups:Y.groups,t:K}),[Y.groups,$.workspaces,$.modulesByWs,$.packagesByWs,$.templates,$.modules,U,v,G,K]),Se=j.useRef(!1);j.useEffect(()=>{if(!Se.current&&$.workspaces.length>0){Se.current=!0;const _=$.workspaces.map(B=>`w:${B.id}`);d==="templates"&&(_.push(Be),A(Be)),X(B=>[...new Set([...B,..._])])}},[$.workspaces,d]);const le=j.useCallback(_=>{const B=xt(ie,_).map(W=>W.id);X(W=>[...new Set([...W,...B])]),A(_)},[ie]),ne=j.useCallback(_=>{Z(null);const B=Ee(_);B&&!$.modules[Q(B)]&&O(B),xe(_)},[$.modules,O]);j.useEffect(()=>{if(!re)return;const _=He(ie,re);if(_){le(_),xe(null);return}const B=Ee(re);if(B&&$.modules[Q(B)]){const W=He(ie,{kind:"module",module:B});W&&le(W),xe(null)}},[re,ie,le,$.modules]);const Ie=j.useCallback(_=>{A(_.id);const B=Ee(_.node);B&&!$.modules[Q(B)]&&O(B),_.node.kind==="module"&&(m==null||m(_.node.module))},[$.modules,O,m]),je=j.useCallback(_=>{const B=ie.byId.get(_);B&&(Ie(B),le(_))},[ie,Ie,le]),$e=j.useRef(!1);j.useEffect(()=>{s&&!$e.current&&$.modulesByWs[s.workspaceId]&&($e.current=!0,O(s).then(()=>m==null?void 0:m(s)),xe({kind:"module",module:s}))},[s,$.modulesByWs,O,m]);const we=ie.byId.get(P),ce=D?"module"in D?D.module:void 0:we?Ee(we.node):void 0,Pe=j.useCallback(async _=>{const B=$.modules[Q(_)];if(!(B!=null&&B.dirty)||ee(_))return;if(p){I({kind:"review",module:_});return}const W=await $.save(_);W&&!W.ok?I({kind:"review",module:_,conflict:W}):W!=null&&W.ok&&(r==null||r(_,W))},[$,ee,p,r]),lt=j.useRef(()=>{});lt.current=()=>{ce&&Pe(ce)},j.useEffect(()=>{const _=V.current;if(!_)return;const B=W=>{(W.ctrlKey||W.metaKey)&&!W.altKey&&W.key.toLowerCase()==="s"&&(W.preventDefault(),lt.current())};return _.addEventListener("keydown",B),()=>_.removeEventListener("keydown",B)},[]);const Dt=()=>{const _=D?St(D):void 0;_?ne(_):Z(null)},Rt=j.useMemo(()=>{if(!D)return[];const _=St(D),B=_?He(ie,_):void 0,W=B?xt(ie,B):[],fe=D.kind==="manifest"?K("devStudio.edit.settings","Settings"):D.kind==="problems"?K("devStudio.overview.problems","Problems"):D.kind==="history"?K("devStudio.overview.history","History"):D.kind==="template"&&!D.templateId?K("devStudio.template.new","New template"):void 0,ve=W.map(ht=>({label:ht.label,onClick:()=>{Z(null),le(ht.id)}}));return fe?ve.push({label:fe}):ve.length>0&&(ve[ve.length-1]={label:ve[ve.length-1].label}),ve},[D,ie,le,K]),ct=!!(o!=null&&o.createModule)&&!!Y.generateModule,Lt=!!(o!=null&&o.createModule)&&!!Y.duplicateModule,Te=$.workspaces.filter(_=>!_.readOnly).map(_=>({id:_.id,label:_.label})),ae=we==null?void 0:we.node,De=ae&&"workspaceId"in ae?ae.workspaceId:ae&&"module"in ae?ae.module.workspaceId:void 0,At=(ae==null?void 0:ae.kind)==="package"?ae.packageId:ae&&"module"in ae?(mt=E(ae.module))==null?void 0:mt.packageId:void 0,Ce=Te.some(_=>_.id===De)?De:(pt=Te[0])==null?void 0:pt.id,qt=y?[]:[...ct&&Ce?[{id:"module",label:K("devStudio.tree.newModule","Module…"),icon:t.jsx(h.NiceIcon,{name:"box",size:14}),onClick:()=>I({kind:"wizard",prefill:{workspaceId:Ce,packageId:Ce===De?At:void 0}})}]:[],...o!=null&&o.savePackage&&Ce?[{id:"package",label:K("devStudio.tree.newPackage","Package…"),icon:t.jsx(h.NiceIcon,{name:"archive",size:14}),onClick:()=>I({kind:"package",workspaceId:Ce})}]:[],...o!=null&&o.saveTemplate&&$.templates?[{id:"template",label:K("devStudio.tree.newTemplate","Template"),icon:t.jsx(h.NiceIcon,{name:"layers",size:14}),onClick:()=>Z({kind:"template",templateId:null})}]:[]],Vt=(_,B)=>{I(_==="delete"?{kind:"delete",module:B}:_==="duplicate"?{kind:"duplicate",module:B}:{kind:"templates",module:B})},ut=w?t.jsx(h.NiceTutorialButton,{steps:h.resolveTutorial(w,un)}):void 0,Fe=ce?$.modules[Q(ce)]:void 0,Re=ce?R(ce):[],Le=$.logs[$.logs.length-1],Wt=t.jsxs("div",{className:"nice-development-studio__statusbar",role:"status",children:[ce&&t.jsxs(t.Fragment,{children:[t.jsx("span",{children:M(ce)}),t.jsx("span",{children:Fe!=null&&Fe.dirty?K("devStudio.status.changed","{count} changed files").replace("{count}",String(Fe.changes.length)):K("devStudio.status.saved","Saved")}),t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:t.jsx(h.NiceIcon,{name:Re.length===0?"check":"warning",size:12}),onClick:()=>Z({kind:"problems",module:ce}),children:Re.length===0?K("devStudio.status.valid","No problems"):K("devStudio.status.problems","{count} problems").replace("{count}",String(Re.length))})]}),t.jsx("span",{className:"nice-development-studio__spacer"}),$.busy?t.jsx("span",{children:K("devStudio.loading","Loading…")}):Le&&t.jsx("span",{className:`nice-development-studio__status-message nice-development-studio__status-message--${Le.level}`,children:Le.message})]}),Ae=(q==null?void 0:q.kind)==="review"?$.modules[Q(q.module)]:void 0,Jt=`nice-development-studio${g?` ${g}`:""}`,Gt=o?K("devStudio.preview.empty","Pick a module, an entity or a view in the tree."):K("devStudio.noProvider","Connect a provider to browse modules.");return t.jsxs("div",{ref:V,id:x,className:Jt,style:{height:S,...k},"data-testid":L??F,children:[t.jsx(h.NiceAppShell,{className:"nice-development-studio__shell",height:"100%",rightSidebar:D?void 0:t.jsx(Qi,{row:we,tree:ie,session:$,preset:Y,provider:o,readOnly:ee,advanced:G,issues:R,canCreateModule:ct,canDuplicateModule:Lt,renderViewPreview:f,emptyText:Gt,onSelect:je,onEdit:Z,onReveal:ne,onSave:_=>void Pe(_),onNewModule:_=>I({kind:"wizard",prefill:_}),onNewPackage:_=>I({kind:"package",workspaceId:_}),onNewTemplate:()=>Z({kind:"template",templateId:null}),onModuleAction:Vt}),rightSidebarWidth:C,statusBar:Wt,bottomPanel:G?t.jsx("div",{"data-tour":"devstudio-output",className:"nice-development-studio__output",children:t.jsx(h.NiceLogConsole,{title:K("devStudio.output","Output"),entries:$.logs,onClear:$.clearLogs,maxHeight:"100%"})}):void 0,bottomPanelHeight:G?140:void 0,children:D?t.jsx(Wi,{screen:D,crumbs:Rt,session:$,preset:Y,provider:o,locales:H,readOnly:ee,advanced:G,issues:R,scriptRunner:b,renderViewPreview:f,modulePanels:v,tutorialButton:ut,onBack:Dt,onSave:_=>void Pe(_),onReveal:ne,onScreen:Z,onNewModule:_=>I({kind:"wizard",prefill:_})}):t.jsx(cn,{tree:ie,selected:P,expanded:te,onExpandedChange:X,onSelect:Ie,loadModule:async _=>{await O(_)},newItems:qt,actions:l,onRefresh:()=>void $.refresh(),tutorialButton:ut,minWidth:N,contextMenuItems:J.menuFor,emptyText:o?K("devStudio.explorer.empty","No modules."):K("devStudio.noProvider","Connect a provider to browse modules.")})}),(q==null?void 0:q.kind)==="wizard"&&t.jsx(yi,{open:!0,onClose:()=>I(null),session:$,preset:Y,locales:H,prefill:q.prefill,onCreated:_=>{m==null||m(_),ne({kind:"module",module:_})}}),(q==null?void 0:q.kind)==="review"&&Ae&&t.jsx(gi,{open:!0,moduleLabel:M(q.module),changes:Ae.changes,original:_=>{var B;return((B=Ae.files.find(W=>W.path===_))==null?void 0:B.text)??""},conflict:q.conflict,onClose:()=>I(null),onSave:async()=>{const _=await $.save(q.module);_!=null&&_.ok?(I(null),r==null||r(q.module,_)):_&&I({...q,conflict:_})},onOverwrite:async()=>{const _=await $.save(q.module,{force:!0});_!=null&&_.ok&&(I(null),r==null||r(q.module,_))},onReload:async()=>{await $.reload(q.module),I(null)}}),(q==null?void 0:q.kind)==="delete"&&t.jsx(h.NiceConfirmDialog,{visible:!0,variant:"warning",header:K("devStudio.delete.title","Delete module"),message:K("devStudio.delete.message","Delete {module} and all its files?").replace("{module}",M(q.module)),acceptLabel:K("devStudio.delete","Delete"),rejectLabel:K("devStudio.cancel","Cancel"),onReject:()=>I(null),onAccept:async()=>{const _=q.module;I(null),await $.deleteModule(_)&&(Z(null),A(`w:${_.workspaceId}`))}}),J.dialog,(q==null?void 0:q.kind)==="duplicate"&&t.jsx(gt,{open:!0,title:K("devStudio.duplicate.title","Duplicate {module}").replace("{module}",M(q.module)),workspaces:Te,workspaceId:Te.some(_=>_.id===q.module.workspaceId)?q.module.workspaceId:void 0,idLabel:K("devStudio.duplicate.id","New module id"),initialId:`${q.module.id}Copy`,onClose:()=>I(null),onSubmit:async _=>{var fe;const B=q.module;I(null);const W=await $.duplicateModule(B,{workspaceId:_.workspaceId,id:_.id,packageId:(fe=E(B))==null?void 0:fe.packageId});W&&ne({kind:"module",module:{workspaceId:W.workspaceId,id:W.id}})}}),(q==null?void 0:q.kind)==="package"&&t.jsx(gt,{open:!0,title:K("devStudio.package.new","New package"),workspaces:Te,workspaceId:q.workspaceId,idLabel:K("devStudio.package.id","Id"),withLabel:!0,onClose:()=>I(null),onSubmit:async _=>{I(null);const B=await $.savePackage({id:_.id,workspaceId:_.workspaceId,label:_.label});B&&ne({kind:"package",workspaceId:B.workspaceId,packageId:B.id})}}),(q==null?void 0:q.kind)==="templates"&&$.templates&&t.jsx(bi,{open:!0,moduleId:q.module.id,templates:$.templates,onClose:()=>I(null),onApply:async _=>{I(null);for(const B of _)await $.saveTemplate(B,B.id)}})]})});exports.addStudioFolder=T.addStudioFolder;exports.addStudioSection=T.addStudioSection;exports.arrayFileKind=T.arrayFileKind;exports.buildDocuments=T.buildDocuments;exports.createMemoryStudioProvider=T.createMemoryStudioProvider;exports.defineManifestSection=T.defineManifestSection;exports.deriveDefaultRbac=T.deriveDefaultRbac;exports.detectJsonTextFormat=T.detectJsonTextFormat;exports.emptyStudioLayout=T.emptyStudioLayout;exports.encodeDocument=T.encodeDocument;exports.endsWithAny=T.endsWithAny;exports.entitiesToSchemas=T.entitiesToSchemas;exports.fileName=T.fileName;exports.fitManifestSection=T.fitManifestSection;exports.i18nFileKind=T.i18nFileKind;exports.isEmptyStudioLayout=T.isEmptyStudioLayout;exports.isStudioLayoutPath=T.isStudioLayoutPath;exports.itemsFileKind=T.itemsFileKind;exports.jsonFallbackKind=T.jsonFallbackKind;exports.jsonFileKind=T.jsonFileKind;exports.jsonValueFitsSchema=T.jsonValueFitsSchema;exports.jsonValuesEqual=T.jsonValuesEqual;exports.keepTextFormat=T.keepTextFormat;exports.manifestSectionKeys=T.manifestSectionKeys;exports.modulePrefix=T.modulePrefix;exports.nativeDataSourcesKind=T.nativeDataSourcesKind;exports.nativeEntitiesKind=T.nativeEntitiesKind;exports.nativeFileKinds=T.nativeFileKinds;exports.nativeHooksKind=T.nativeHooksKind;exports.nativeI18nKind=T.nativeI18nKind;exports.nativeManifestKind=T.nativeManifestKind;exports.nativeRbacKind=T.nativeRbacKind;exports.nativeStudioPreset=T.nativeStudioPreset;exports.nativeViewsKind=T.nativeViewsKind;exports.nativeWorkflowsKind=T.nativeWorkflowsKind;exports.objectFileKind=T.objectFileKind;exports.parseJsonText=T.parseJsonText;exports.parseStudioLayout=T.parseStudioLayout;exports.patchJsonText=T.patchJsonText;exports.patchJsonTextDetailed=T.patchJsonTextDetailed;exports.placeStudioEntry=T.placeStudioEntry;exports.readTranslations=T.readTranslations;exports.removeStudioLayoutNode=T.removeStudioLayoutNode;exports.renameStudioEntryRef=T.renameStudioEntryRef;exports.renameStudioLayoutNode=T.renameStudioLayoutNode;exports.resolveFileKind=T.resolveFileKind;exports.safeJson=T.safeJson;exports.serializeStudioLayout=T.serializeStudioLayout;exports.slugifyModuleId=T.slugifyModuleId;exports.stringifyJsonText=T.stringifyJsonText;exports.studioEntryRef=T.studioEntryRef;exports.studioLayoutPath=T.studioLayoutPath;exports.textFallbackKind=T.textFallbackKind;exports.writeTranslations=T.writeTranslations;exports.NiceArrayField=tt;exports.NiceDevelopmentStudio=pn;exports.NiceEntityEditor=Tt;exports.NiceEntityForm=it;exports.NiceI18nEditor=st;exports.NiceSchemaForm=_e;exports.aiFormConfigToFormFields=Qt;exports.aiFormFieldType=Nt;exports.formBuilderSchemaToNiceFormItems=Ht;exports.formFieldsToFormItems=Qe;exports.formSchemaToJsonSchema=ni;exports.jsonSchemaToFormItems=Ze;exports.schemaToFormItems=Yt;exports.validateAgainstJsonSchema=et;exports.validateFormSchema=Xt;
|
|
5
|
+
`]},d))})}function Ei({open:e,onClose:i,session:n,preset:o,locales:a,prefill:s,onCreated:d}){var M,N,k,x;const{t:l}=h.useNiceTranslation(),u=n.workspaces.filter(w=>!w.readOnly),m=o.requiredLocales??[],[r,c]=j.useState(()=>{var w;return{workspaceId:s.workspaceId&&u.some(_=>_.id===s.workspaceId)?s.workspaceId:((w=u[0])==null?void 0:w.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([...m,...a.slice(0,2)])],views:!0,permissions:!0}}),[p,g]=j.useState(null),[S,f]=j.useState(!1),v=j.useMemo(()=>[...new Set((n.modulesByWs[r.workspaceId]??[]).map(w=>w.packageId).filter(Boolean))].sort(),[n.modulesByWs,r.workspaceId]);if(!e)return null;const y=new Set(Object.values(n.modulesByWs).flatMap(w=>w.map(_=>_.id))),b=async()=>{o.generateModule&&r.name.trim()&&g(await o.generateModule({...r,name:r.name.trim()},{existingIds:y}))};return t.jsx(h.NiceModal,{open:e,onClose:i,title:l("devStudio.wizard.title","New module"),size:"xl","data-testid":"studio-module-wizard",children:t.jsx(h.NiceWizard,{finishLabel:l("devStudio.wizard.create","Create module"),onCancel:i,onStepChange:w=>{w===3&&b()},onComplete:async()=>{if(S)return;f(!0);const w=await n.createModule({...r,name:r.name.trim()});f(!1),w&&(d({workspaceId:w.workspaceId,id:w.id}),i())},steps:[{id:"identity",title:l("devStudio.wizard.identity","Name and place"),validate:()=>r.name.trim()&&r.workspaceId?!0:l("devStudio.wizard.needName","Give the module a name."),content:t.jsxs("div",{className:"nice-development-studio__form",children:[t.jsx(h.NiceSelect,{label:l("devStudio.wizard.workspace","Project"),value:r.workspaceId,options:u.map(w=>({value:w.id,label:w.label})),onChange:w=>c({...r,workspaceId:String(w)})}),t.jsx(h.NiceTextInput,{label:l("devStudio.wizard.package","Package"),value:r.packageId??"",placeholder:v.join(", "),onChange:w=>c({...r,packageId:w||void 0})}),t.jsx(h.NiceTextInput,{label:l("devStudio.wizard.name","Name"),value:r.name,placeholder:l("devStudio.wizard.namePlaceholder","e.g. Bike rental"),onChange:w=>c({...r,name:w})}),t.jsx(h.NiceTextInput,{label:l("devStudio.wizard.description","Description"),value:r.description??"",onChange:w=>c({...r,description:w||void 0})})]})},{id:"entities",title:l("devStudio.wizard.entities","Entities"),content:t.jsx(Ft,{value:r.entities,onChange:w=>c({...r,entities:w}),entityMetaSchema:(M=o.entities)==null?void 0:M.entityMetaSchema,fieldSchema:(N=o.entities)==null?void 0:N.fieldSchema,fieldsKey:(k=o.entities)==null?void 0:k.fieldsKey,nameKey:(x=o.entities)==null?void 0:x.nameKey})},{id:"options",title:l("devStudio.wizard.options","Options"),content:t.jsxs("div",{className:"nice-development-studio__form",children:[t.jsxs("fieldset",{className:"nice-development-studio__fieldset",children:[t.jsx("legend",{children:l("devStudio.wizard.locales","Languages")}),[...new Set([...m,...a])].map(w=>t.jsx(h.NiceCheckbox,{label:w,checked:r.locales.includes(w),disabled:m.includes(w),onChange:_=>c({...r,locales:_?[...r.locales,w]:r.locales.filter(z=>z!==w)})},w))]}),t.jsx(h.NiceCheckbox,{label:l("devStudio.wizard.views","A list and a form view per entity"),checked:!!r.views,onChange:w=>c({...r,views:w})}),t.jsx(h.NiceCheckbox,{label:l("devStudio.wizard.permissions","Viewer, editor and admin permissions"),checked:!!r.permissions,onChange:w=>c({...r,permissions:w})})]})},{id:"review",title:l("devStudio.wizard.review","Review"),content:p?t.jsxs("div",{children:[t.jsx("p",{children:l("devStudio.wizard.willCreate","Module {id} with these files:").replace("{id}",p.id)}),t.jsx("ul",{className:"nice-development-studio__list",children:p.files.map(w=>t.jsxs("li",{children:[t.jsx(h.NiceIcon,{name:"file",size:12})," ",w.path]},w.path))})]}):t.jsx("p",{className:"nice-development-studio__muted",children:l("devStudio.wizard.generating","Generating…")})}]})})}function $i({open:e,moduleLabel:i,changes:n,original:o,conflict:a,onSave:s,onOverwrite:d,onReload:l,onClose:u}){const{t:m}=h.useNiceTranslation();return e?t.jsxs(h.NiceModal,{open:e,onClose:u,size:"xl",title:m("devStudio.review.title","Save {module}").replace("{module}",i),"data-testid":"studio-review",footer:a?t.jsxs(t.Fragment,{children:[t.jsx(h.NiceButton,{variant:"ghost",onClick:u,children:m("devStudio.cancel","Cancel")}),t.jsx(h.NiceButton,{variant:"secondary",onClick:l,children:m("devStudio.review.reload","Reload theirs (drop mine)")}),t.jsx(h.NiceButton,{variant:"danger",onClick:d,children:m("devStudio.review.overwrite","Overwrite with mine")})]}):t.jsxs(t.Fragment,{children:[t.jsx(h.NiceButton,{variant:"ghost",onClick:u,children:m("devStudio.cancel","Cancel")}),t.jsx(h.NiceButton,{variant:"primary",onClick:s,children:m("devStudio.review.save","Save {count} files").replace("{count}",String(n.length))})]}),children:[a&&t.jsxs("p",{className:"nice-development-studio__error",role:"alert",children:[m("devStudio.review.conflict","These files changed since you opened them:")," ",a.conflicts.map(r=>r.path).join(", ")]}),n.map(r=>t.jsxs("section",{className:"nice-development-studio__source",children:[t.jsx("h4",{className:"nice-development-studio__source-title",children:r.type==="delete"?m("devStudio.change.delete","Delete {path}").replace("{path}",r.path):r.baseVersion===void 0&&!o(r.path)?m("devStudio.change.new","New file {path}").replace("{path}",r.path):r.path}),t.jsx(Mt,{before:o(r.path),after:r.type==="write"?r.text:""})]},r.path))]}):null}function Fi({open:e,moduleId:i,templates:n,onApply:o,onClose:a}){const{t:s}=h.useNiceTranslation(),d=j.useMemo(()=>n.filter(c=>c.modules.some(p=>p.moduleId===i)).map(c=>c.id),[n,i]),[l,u]=j.useState(d);if(!e)return null;const m=n.map(c=>{var p,g;return{id:c.id,label:((p=c.translations.en)==null?void 0:p.name)??((g=Object.values(c.translations)[0])==null?void 0:g.name)??c.id}}),r=[{field:"label",header:s("devStudio.explorer.name","Name")}];return t.jsx(h.NiceModal,{open:e,onClose:a,title:s("devStudio.picker.title","Templates with {module}").replace("{module}",i),"data-testid":"studio-template-picker",footer:t.jsxs(t.Fragment,{children:[t.jsx(h.NiceButton,{variant:"ghost",onClick:a,children:s("devStudio.cancel","Cancel")}),t.jsx(h.NiceButton,{variant:"primary",onClick:()=>{const c=n.filter(p=>l.includes(p.id)!==d.includes(p.id)).map(p=>({...p,modules:l.includes(p.id)?[...p.modules,{moduleId:i}]:p.modules.filter(g=>g.moduleId!==i)}));o(c)},children:s("devStudio.apply","Apply")})]}),children:t.jsx(h.NiceTreeGrid,{data:m,columns:r,keyField:"id",sortable:!1,compact:!0,checkable:!0,checkedKeys:l,onCheckedChange:u,searchable:!0,"aria-label":s("devStudio.explorer.templates","Templates")})})}function jt({open:e,title:i,workspaces:n,workspaceId:o,idLabel:a,initialId:s="",withLabel:d,onSubmit:l,onClose:u}){var v;const{t:m}=h.useNiceTranslation(),[r,c]=j.useState(o??((v=n[0])==null?void 0:v.id)??""),[p,g]=j.useState(s),[S,f]=j.useState("");return e?t.jsx(h.NiceModal,{open:e,onClose:u,title:i,footer:t.jsxs(t.Fragment,{children:[t.jsx(h.NiceButton,{variant:"ghost",onClick:u,children:m("devStudio.cancel","Cancel")}),t.jsx(h.NiceButton,{variant:"primary",disabled:!p.trim()||!r,onClick:()=>l({workspaceId:r,id:p.trim(),label:S.trim()||p.trim()}),children:m("devStudio.ok","OK")})]}),children:t.jsxs("div",{className:"nice-development-studio__form",children:[t.jsx(h.NiceSelect,{label:m("devStudio.wizard.workspace","Project"),value:r,options:n.map(y=>({value:y.id,label:y.label})),onChange:y=>c(String(y))}),t.jsx(h.NiceTextInput,{label:a,value:p,onChange:g}),d&&t.jsx(h.NiceTextInput,{label:m("devStudio.package.label","Name"),value:S,onChange:f})]})}):null}const Nt=e=>JSON.stringify(e??null,null,2);function ot({value:e,onChange:i,readOnly:n,height:o=320,label:a}){const{t:s}=h.useNiceTranslation(),[d,l]=j.useState(()=>Nt(e)),[u,m]=j.useState(null),r=j.useRef(e);return j.useEffect(()=>{r.current!==e&&(r.current=e,l(Nt(e)),m(null))},[e]),t.jsxs("div",{className:"nice-development-studio__json",role:"group","aria-label":a,children:[t.jsx(h.NiceSimpleCodeEditor,{value:d,language:"json",height:o,readOnly:n,lineNumbers:!0,onChange:c=>{l(c);try{const p=JSON.parse(c);m(null),r.current=p,i==null||i(p)}catch(p){m(p instanceof Error?p.message:String(p))}}}),u&&t.jsxs("p",{className:"nice-development-studio__error",role:"alert",children:[s("devStudio.json.invalid","Not valid JSON:")," ",u]})]})}const Mi=[{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"}],at=j.forwardRef(function(i,n){const{value:o,defaultValue:a,onChange:s,locales:d,allowEditLocales:l=!0,allowEditKeys:u=!0,highlightMissing:m=!0,readOnly:r=!1,tutorial:c,className:p,style:g,id:S,"data-testid":f}=i,{t:v}=ke.useNiceTranslation(),[y,b]=ke.useControllableState({value:o,defaultValue:a,fallbackValue:{},onChange:s,componentName:"NiceI18nEditor"}),[M,N]=j.useState(""),[k,x]=j.useState(""),w=j.useMemo(()=>d??Object.keys(y),[d,y]),_=j.useMemo(()=>{const T=new Set;for(const L of Object.keys(y))for(const R of Object.keys(y[L]??{}))T.add(R);return[...T].sort()},[y]),z=(T,L,R)=>{b({...y,[T]:{...y[T]??{},[L]:R}})},K=(T,L)=>{if(!L||L===T)return;const R={};for(const H of Object.keys(y)){const Q={...y[H]??{}};T in Q&&(Q[L]=Q[T],delete Q[T]),R[H]=Q}b(R)},C=T=>{const L={};for(const R of Object.keys(y)){const H={...y[R]??{}};delete H[T],L[R]=H}b(L)},V=()=>{const T=M.trim();if(!T||_.includes(T))return;const L={};for(const R of w)L[R]={...y[R]??{},[T]:""};for(const R of Object.keys(y))L[R]||(L[R]=y[R]);b(L),N("")},X=()=>{const T=k.trim();if(!T||y[T])return;const L={};for(const R of _)L[R]="";b({...y,[T]:L}),x("")},A=T=>{const L={...y};delete L[T],b(L)},ne="nice-i18n-editor"+(p?` ${p}`:"");return t.jsxs("div",{ref:n,id:S,className:ne,style:g,"data-testid":f,children:[c&&t.jsx("div",{className:"nice-i18n-editor__tutorial",children:t.jsx(ke.NiceTutorialButton,{steps:ke.resolveTutorial(c,Mi)})}),t.jsx("div",{className:"nice-i18n-editor__scroll","data-tour":"i18n-grid",children:t.jsxs("table",{className:"nice-i18n-editor__table",children:[t.jsx("thead",{children:t.jsxs("tr",{children:[t.jsx("th",{className:"nice-i18n-editor__key-head",children:v("i18nEditor.keyHead","Key")}),w.map(T=>t.jsxs("th",{className:"nice-i18n-editor__locale-head",children:[t.jsx("span",{children:T}),l&&!r&&t.jsx("button",{type:"button",className:"nice-i18n-editor__locale-remove","aria-label":`${v("i18nEditor.removeLocale","Remove locale")} ${T}`,onClick:()=>A(T),children:t.jsx(ke.NiceIcon,{name:"close",size:12})})]},T))]})}),t.jsxs("tbody",{children:[_.map(T=>t.jsxs("tr",{children:[t.jsxs("td",{className:"nice-i18n-editor__key-cell",children:[u&&!r?t.jsx("input",{className:"nice-i18n-editor__key-input",defaultValue:T,onBlur:L=>K(T,L.target.value.trim()),"aria-label":v("i18nEditor.keyAria","Translation key")}):t.jsx("span",{className:"nice-i18n-editor__key-text",children:T}),u&&!r&&t.jsx("button",{type:"button",className:"nice-i18n-editor__key-remove","aria-label":`${v("i18nEditor.removeKey","Remove key")} ${T}`,onClick:()=>C(T),children:t.jsx(ke.NiceIcon,{name:"close",size:12})})]}),w.map(L=>{var Q;const R=((Q=y[L])==null?void 0:Q[T])??"",H=m&&R==="";return t.jsx("td",{className:"nice-i18n-editor__cell",children:t.jsx("input",{className:"nice-i18n-editor__cell-input"+(H?" nice-i18n-editor__cell-input--missing":""),value:R,readOnly:r,onChange:J=>z(L,T,J.target.value),"aria-label":`${T} (${L})`})},L)})]},T)),_.length===0&&t.jsx("tr",{children:t.jsx("td",{className:"nice-i18n-editor__empty",colSpan:w.length+1,children:v("i18nEditor.empty","No translation keys yet.")})})]})]})}),!r&&(u||l)&&t.jsxs("div",{className:"nice-i18n-editor__toolbar","data-tour":"i18n-add",children:[u&&t.jsxs("div",{className:"nice-i18n-editor__add",children:[t.jsx("input",{className:"nice-i18n-editor__add-input",placeholder:v("i18nEditor.newKeyPlaceholder","new.key"),value:M,onChange:T=>N(T.target.value),onKeyDown:T=>{T.key==="Enter"&&V()},"aria-label":v("i18nEditor.newKeyAria","New key")}),t.jsxs("button",{type:"button",onClick:V,children:["+ ",v("i18nEditor.addKey","Key")]})]}),l&&t.jsxs("div",{className:"nice-i18n-editor__add",children:[t.jsx("input",{className:"nice-i18n-editor__add-input",placeholder:v("i18nEditor.newLocalePlaceholder","locale (e.g. de)"),value:k,onChange:T=>x(T.target.value),onKeyDown:T=>{T.key==="Enter"&&X()},"aria-label":v("i18nEditor.newLocaleAria","New locale")}),t.jsxs("button",{type:"button",onClick:X,children:["+ ",v("i18nEditor.addLocale","Locale")]})]})]})]})}),Y=e=>`${e.workspaceId}/${e.id}`;function He(e,i,n){const o=new Set(e.deleted),a=new Map;for(const p of e.files)o.has(p.path)||a.set(p.path,e.raw[p.path]!==void 0?{...p,text:e.raw[p.path]}:p);for(const[p,g]of Object.entries(e.raw))!a.has(p)&&!o.has(p)&&a.set(p,{path:p,text:g});const s=[...a.values()],d={moduleId:e.key.id,files:s,locales:n},l=$.buildDocuments(i.kinds,s,d),u=new Map(s.map(p=>[p.path,p.text])),m={};for(const p of l)if(p.key in e.drafts)try{const g=p.kind.encode(e.drafts[p.key],s.filter(S=>p.paths.includes(S.path)),d);for(const S of g.files)u.set(S.path,S.text),o.delete(S.path);for(const S of g.deleted??[])u.delete(S),o.add(S)}catch(g){m[p.key]=g instanceof Error?g.message:String(g)}const r=new Map(e.files.map(p=>[p.path,p])),c=[];for(const[p,g]of u){const S=r.get(p);(!S||S.text!==g)&&c.push({type:"write",path:p,text:g,baseVersion:S==null?void 0:S.version})}for(const p of o){const g=r.get(p);g&&c.push({type:"delete",path:p,baseVersion:g.version})}return{...e,working:s,documents:l,changes:c,pending:u,encodeErrors:m,dirty:c.length>0}}function Kt(e,i){const n=[];for(const o of e.documents){if(o.error&&n.push({severity:"error",code:"file.unreadable",message:`${o.paths[0]} cannot be read: ${o.error}`,messageKey:"devStudio.issue.unreadable",params:{path:o.paths[0]},moduleId:e.key.id,path:o.paths[0]}),o.kind.editor!=="manifest"||!i.manifestSections)continue;const a=e.drafts[o.key]??o.model??{};for(const s of i.manifestSections){const{section:d}=$.fitManifestSection(s,a);if(d.schema)for(const l of it(a,d.schema))n.push({severity:"error",code:"manifest.schema",message:`${d.title}: ${l.field} — ${l.message}`,moduleId:e.key.id,path:o.paths[0],pointer:`/${l.field.replace(/\./g,"/")}`})}}for(const[o,a]of Object.entries(e.encodeErrors))n.push({severity:"error",code:"document.encode",message:`${o}: ${a}`,moduleId:e.key.id});if(i.validateModule){const o=[...e.pending.entries()].map(([a,s])=>({path:a,text:s}));n.push(...i.validateModule({key:e.key,files:o,documents:e.documents,contents:e.contents}).map(a=>({...a,moduleId:a.moduleId??e.key.id})))}return n}const Ki=(e,i={})=>Object.entries(i).reduce((n,[o,a])=>n.split(`{${o}}`).join(String(a)),e),Oi=e=>e instanceof Error?e.message:String(e);function zi(e,i,n){const[o,a]=j.useState([]),[s,d]=j.useState({}),l=j.useRef(s);l.current=s;const[u,m]=j.useState({}),[r,c]=j.useState(null),[p,g]=j.useState({}),[S,f]=j.useState({}),[v,y]=j.useState(0),[b,M]=j.useState([]),N=j.useRef({provider:e,preset:i,options:n});N.current={provider:e,preset:i,options:n};const k=j.useCallback((I,F,O)=>{var D,B;return Ki(((B=(D=N.current.options).t)==null?void 0:B.call(D,I,F))??F,O)},[]),x=j.useCallback((I,F,O)=>{M(D=>[...D,{level:I,message:F,data:O,timestamp:Date.now()}].slice(-300))},[]),w=j.useCallback(async(I,F)=>{var O,D;y(B=>B+1);try{return await F()}catch(B){x("error",`${I}: ${Oi(B)}`),(D=(O=N.current.options).onError)==null||D.call(O,B,I);return}finally{y(B=>B-1)}},[x]),_=j.useCallback(async()=>{const I=N.current.provider;I&&await w(k("devStudio.log.list","List"),async()=>{const F=await I.listWorkspaces();a(F);const O=await Promise.all(F.map(async D=>{const[B,G]=await Promise.all([I.listModules(D.id),I.listPackages?I.listPackages(D.id):Promise.resolve(void 0)]);return[D.id,B,G]}));d(Object.fromEntries(O.map(([D,B])=>[D,B]))),m(Object.fromEntries(O.filter(([,,D])=>D).map(([D,,B])=>[D,B]))),c(I.listTemplates?await I.listTemplates():null)})},[w,k]);j.useEffect(()=>{_()},[e,_]);const z=j.useMemo(()=>{const I={};for(const[F,O]of Object.entries(p))I[F]=He(O,i,n.locales);return I},[p,i,n.locales]),K=j.useCallback(async I=>{var Z,q;const F=Y(I),O=N.current.provider;if(!O)return;const D=await w(k("devStudio.log.open","Open {id}",{id:I.id}),()=>O.readModule(I));if(!D)return;const B=(q=(Z=l.current[I.workspaceId])==null?void 0:Z.find(ae=>ae.id===I.id))==null?void 0:q.contents,G={key:I,files:D,raw:{},deleted:[],drafts:{},contents:B};return g(ae=>ae[F]?ae:{...ae,[F]:G}),x("info",k("devStudio.log.opened","Opened {id} ({count} files)",{id:I.id,count:D.length})),He(G,N.current.preset,N.current.options.locales)},[w,x,k]),C=j.useCallback((I,F)=>{const O=Y(I);g(D=>D[O]?{...D,[O]:F(D[O])}:D)},[]),V=j.useCallback((I,F,O)=>C(I,D=>({...D,drafts:{...D.drafts,[F]:O}})),[C]),X=j.useCallback((I,F,O,D=[])=>C(I,B=>{const G={...B.raw};O===null?delete G[F]:G[F]=O;const Z={...B.drafts};for(const q of D)delete Z[q];return{...B,raw:G,drafts:Z,deleted:B.deleted.filter(q=>q!==F)}}),[C]),A=j.useCallback((I,F)=>C(I,O=>{const D={...O.raw};delete D[F];const B=!O.files.some(G=>G.path===F);return{...O,raw:D,deleted:B?O.deleted:[...new Set([...O.deleted,F])]}}),[C]),ne=j.useCallback(I=>C(I,F=>({...F,raw:{},deleted:[],drafts:{}})),[C]),T=j.useCallback(async I=>{const F=N.current.provider;if(!F)return;const O=await w(k("devStudio.log.reload","Reload {id}",{id:I.id}),()=>F.readModule(I));O&&(C(I,D=>({key:I,files:O,raw:{},deleted:[],drafts:{},contents:D.contents})),x("info",k("devStudio.log.reloaded","Reloaded {id}",{id:I.id})))},[w,C,x,k]),L=j.useCallback(I=>{const F=Y(I);g(O=>{const D={...O};return delete D[F],D})},[]),R=j.useCallback(async(I,F={})=>{var Ce;const O=N.current.provider,D=Y(I),B=p[D];if(!O||!B)return;const G=He(B,N.current.preset,N.current.options.locales);if(G.changes.length===0)return{ok:!0};const Z=F.force?G.changes.map(ee=>({...ee,baseVersion:void 0})):G.changes,q=await w(k("devStudio.log.save","Save {id}",{id:I.id}),()=>O.writeModule(I,Z));if(!q)return;if(!q.ok)return x("warn",k("devStudio.log.conflicts","{id}: {count} file(s) changed meanwhile",{id:I.id,count:q.conflicts.length})),q;const ae=[];for(const[ee,pe]of G.pending){const he=B.files.find(Le=>Le.path===ee);ae.push({...he,path:ee,text:pe,version:((Ce=q.versions)==null?void 0:Ce[ee])??(he==null?void 0:he.version)})}C(I,ee=>({key:I,files:ae,raw:{},deleted:[],drafts:{},contents:ee.contents}));const se=Z.map(ee=>ee.type==="delete"?k("devStudio.log.changeDelete","delete {path}",{path:ee.path}):k("devStudio.log.changeWrite","write {path}",{path:ee.path})).join(", ");return x("info",k("devStudio.log.saved","Saved {id}: {changes}",{id:I.id,changes:se})),q},[p,w,C,x,k]),H=j.useCallback(async I=>{const F=Y(I),O=z[F];if(!O)return[];const D=Kt(O,i),B=N.current.provider;let G=[];if(B!=null&&B.validate){const q=[...O.pending.entries()].map(([ae,se])=>({path:ae,text:se}));G=await w(k("devStudio.log.validate","Validate {id}",{id:I.id}),()=>B.validate(I,q))??[]}f(q=>({...q,[F]:G}));const Z=[...D,...G];x(Z.some(q=>q.severity==="error")?"warn":"info",Z.length===0?k("devStudio.log.noProblems","{id}: no problems",{id:I.id}):k("devStudio.log.problems","{id}: {count} problem(s)",{id:I.id,count:Z.length}));for(const q of Z)x(q.severity==="error"?"error":q.severity==="warning"?"warn":"info",`${q.path?`${q.path}: `:""}${q.messageKey?k(q.messageKey,q.message,q.params):q.message}`);return Z},[z,i,w,x,k]),Q=j.useCallback(async I=>{const{provider:F,preset:O}=N.current;if(!(F!=null&&F.createModule)||!O.generateModule)return;const D=new Set(Object.values(s).flatMap(Z=>Z.map(q=>q.id))),B=await w(k("devStudio.log.generate","Generate module"),()=>O.generateModule(I,{existingIds:D}));if(!B)return;const G=await w(k("devStudio.log.create","Create {id}",{id:B.id}),()=>F.createModule({workspaceId:I.workspaceId,packageId:B.packageId??I.packageId,id:B.id,files:B.files}));return G&&(x("info",k("devStudio.log.created","Created {id}",{id:G.id})),await _()),G},[s,w,x,_,k]),J=j.useCallback(async(I,F)=>{const{provider:O,preset:D}=N.current;if(!(O!=null&&O.createModule)||!D.duplicateModule)return;const B=await w(k("devStudio.log.read","Read {id}",{id:I.id}),()=>O.readModule(I));if(!B)return;const G=await w(k("devStudio.log.duplicate","Duplicate"),()=>D.duplicateModule(B,F));if(!G)return;const Z=await w(k("devStudio.log.create","Create {id}",{id:G.id}),()=>O.createModule({workspaceId:F.workspaceId,packageId:G.packageId??F.packageId,id:G.id,files:G.files}));return Z&&(x("info",k("devStudio.log.duplicated","Duplicated {id} as {copy}",{id:I.id,copy:Z.id})),await _()),Z},[w,x,_,k]),U=j.useCallback(async I=>{const F=N.current.provider;if(!(F!=null&&F.deleteModule))return!1;const O=await w(k("devStudio.log.delete","Delete {id}",{id:I.id}),async()=>(await F.deleteModule(I),!0));return O&&(L(I),x("info",k("devStudio.log.deleted","Deleted {id}",{id:I.id})),await _()),!!O},[w,L,x,_,k]),oe=j.useCallback(async I=>{const F=N.current.provider;if(!(F!=null&&F.savePackage))return;const O=await w(k("devStudio.log.savePackage","Save package {id}",{id:I.id}),()=>F.savePackage(I));return O&&(x("info",k("devStudio.log.savedPackage","Saved package {id}",{id:O.id})),await _()),O},[w,x,_,k]),Ne=j.useCallback(async(I,F)=>{const O=N.current.provider;if(!(O!=null&&O.saveTemplate))return;const D=await w(k("devStudio.log.saveTemplate","Save template {id}",{id:I.id}),()=>O.saveTemplate(I,F?{previousId:F}:void 0));return D&&O.listTemplates&&(c(await O.listTemplates()),x("info",k("devStudio.log.savedTemplate","Saved template {id}",{id:D.id}))),D},[w,x,k]),we=j.useCallback(async I=>{const F=N.current.provider;if(!(F!=null&&F.deleteTemplate))return!1;const O=await w(k("devStudio.log.deleteTemplate","Delete template {id}",{id:I}),async()=>(await F.deleteTemplate(I),!0));return O&&F.listTemplates&&(c(await F.listTemplates()),x("info",k("devStudio.log.deletedTemplate","Deleted template {id}",{id:I}))),!!O},[w,x,k]);return{workspaces:o,modulesByWs:s,packagesByWs:u,templates:r,modules:z,serverIssues:S,busy:v>0,logs:b,clearLogs:()=>M([]),log:x,refresh:_,openModule:K,close:L,setDraft:V,setRaw:X,deleteFile:A,discard:ne,reload:T,save:R,validate:H,createModule:Q,duplicateModule:J,deleteModule:U,savePackage:oe,saveTemplate:Ne,deleteTemplate:we}}const ue="__none",ze="t:",Pi={entities:"entities",views:"views",workflows:"workflows",i18n:"translations",permissions:"permissions",rbac:"access",dataSources:"dataSources",seeds:"seeds",hooks:"hooks",script:"scripts",scriptList:"scripts"},Di=["entities","views","workflows","translations","permissions","access","dataSources","seeds","hooks","scripts"],dt={entities:"database",views:"grid",workflows:"git-branch",translations:"globe",permissions:"shield",access:"users",dataSources:"server",seeds:"list",hooks:"zap",scripts:"code",files:"folder"},Ot={views:"grid",workflows:"git-branch",dataSources:"server",scripts:"code"},zt={frontend:"code",backend:"server",noCode:"list",sql:"database"},Pt=e=>e.kind.treeGroup??Pi[e.kind.editor],Dt=e=>e==="views"||e==="workflows"||e==="dataSources",je=(e,i)=>i.kind.editor==="scriptList"?ie(e,i):void 0,De=e=>Object.prototype.hasOwnProperty.call(dt,e),ve=(e,i)=>De(e)?dt[e]:(i==null?void 0:i.icon)??"folder";function fe(e,i,n,o){const a=(s,d)=>e(s,d).replace("{count}",String(n??0));if(!De(i)){const s=o?e(o.labelKey??`devStudio.group.${i}`,o.label):i;return n===void 0?s:`${s}: ${n}`}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 e("devStudio.group.translations","Translations");case"permissions":return e("devStudio.group.permissions","Permissions");case"access":return e("devStudio.group.access","Access");case"seeds":return e("devStudio.group.seeds","Seed data");case"hooks":return e("devStudio.group.hooks","Lifecycle hooks")}}function Lt(e){switch(e.kind){case"workspace":return`w|${e.workspaceId}`;case"package":return`p|${e.workspaceId}|${e.packageId??ue}`;case"module":return`m|${Y(e.module)}`;case"group":return`g|${Y(e.module)}|${e.group}${e.section?`|${e.section}`:""}`;case"section":return`s|${Y(e.module)}|${e.sectionId}`;case"folder":return`fo|${Y(e.module)}|${e.folderId}`;case"entity":return`e|${Y(e.module)}|${e.docKey}|${e.index}`;case"item":return`i|${Y(e.module)}|${e.group}|${e.docKey}|${e.itemKey}`;case"document":return`d|${Y(e.module)}|${e.docKey}`;case"panel":return`x|${Y(e.module)}|${e.panelKey}`;case"file":return`f|${Y(e.module)}|${e.path}`;case"templates":return"t";case"category":return`c|${e.category}`;case"template":return`t|${e.templateId}`;case"templateModule":return`tm|${e.templateId}|${e.moduleId}`}}const ie=(e,i)=>e.drafts[i.key]??i.model,me=(e,i)=>e.documents.find(n=>n.key===i),be=(e,i)=>e.changes.some(n=>i.paths.includes(n.path));function rt(e){const i=[];for(const n of e.documents){if(n.kind.editor!=="entities")continue;const o=ie(e,n);Array.isArray(o)&&o.forEach((a,s)=>i.push({docKey:n.key,index:s,entity:a}))}return i}const Xe=e=>rt(e).map(i=>i.entity),lt=(e,i="name")=>String(e.displayName||e[i]||"");function le(e,i){var o;if(i.kind.editor==="scriptList"){const a=(o=je(e,i))==null?void 0:o.scripts;return Array.isArray(a)?a:[]}const n=ie(e,i);return Array.isArray(n)?i.kind.editor==="dataSources"?n.map(a=>{const s=a;return{key:String(s.key??""),label:s.label||String(s.key??""),definition:a,source:a}}):n:[]}function ct(e,i,n){return n===null?e.filter((o,a)=>a!==i):e.map((o,a)=>a===i?n:o)}function ut(e,i,n){return i.kind.editor==="scriptList"?{...je(e,i)??{scripts:[]},scripts:n}:n}function Bt(e,i,n){return n===null?e.filter(o=>o.key!==i):e.map(o=>o.key===i?n:o)}function Rt(e,i,n){const o=new Map((i??[]).map(a=>[a.id,a]));for(const a of n){const s=a.packageId??ue;o.has(s)||o.set(s,{id:s,workspaceId:e,label:a.packageId??"",derived:!0})}return[...o.values()].sort((a,s)=>a.id===ue?1:s.id===ue?-1:a.label.localeCompare(s.label))}const Ke=(e,i)=>e&&/^[a-z0-9-]+$/.test(e)?e:i,Pe=e=>e.slice(e.lastIndexOf("/")+1);function At(e){var n;const i=$.studioLayoutPath(e.working);return $.parseStudioLayout((n=e.working.find(o=>o.path===i))==null?void 0:n.text)}function Li(e){const i=[...Di],n=[...e??[]].filter(a=>!i.includes(a.id)).sort((a,s)=>(a.order??1e3)-(s.order??1e3)),o=[...i];for(const a of n){const s=a.order===void 0?o.length:Math.min(o.length,Math.max(0,Math.floor(a.order/10)));o.splice(s,0,a.id)}return o}function Bi(e,i,n){var r;const{t:o}=n,a=i.key,s=c=>{var p;return(p=n.groups)==null?void 0:p.find(g=>g.id===c)},d=new Map;for(const c of i.documents){const p=Pt(c);p&&d.set(p,[...d.get(p)??[],c])}const l=(c,p)=>({id:`${p}/d:${c.key}`,node:{kind:"document",module:a,docKey:c.key},label:Pe(c.paths[0]??c.label),icon:"warning",noForm:!0,dirty:be(i,c)}),u=[];for(const c of Li(n.groups)){const p=d.get(c);if(!p)continue;const g=s(c),S=`${e}/g:${c}`,f={kind:"group",module:a,group:c};if(c==="entities"){const v=[];for(const b of p){const M=ie(i,b);if(!Array.isArray(M)){v.push(l(b,S));continue}const N=be(i,b);M.forEach((k,x)=>{const w=k.fields;v.push({id:`${S}/e:${b.key}#${x}`,node:{kind:"entity",module:a,docKey:b.key,index:x},label:lt(k)||`#${x+1}`,icon:"table",info:Array.isArray(w)?String(w.length):void 0,dirty:N,search:String(k.name??""),ref:`entities:${String(k.name??`#${x}`)}`})})}const y=v.filter(b=>b.node.kind==="entity").length;u.push({id:S,node:f,label:fe(o,c,y),icon:ve(c,g),children:v});continue}if(c==="scripts"){u.push({id:S,node:f,icon:ve(c,g),...Ri(S,i,p,o)});continue}if(Dt(c)){const v=[];for(const b of p){if(b.model===void 0){v.push(l(b,S));continue}const M=be(i,b);for(const N of le(i,b))v.push({id:`${S}/i:${b.key}#${N.key}`,node:{kind:"item",module:a,group:c,docKey:b.key,itemKey:N.key},label:N.label||N.key,icon:Ot[c],noForm:N.definition===void 0,dirty:M,search:N.key,ref:`${c}:${N.key}`})}const y=v.filter(b=>b.node.kind==="item").length;u.push({id:S,node:f,label:fe(o,c,y),icon:ve(c,g),children:v});continue}if(!De(c)){u.push({id:S,node:f,label:fe(o,c,p.length,g),icon:ve(c,g),children:p.map(v=>({id:`${S}/d:${v.key}`,node:{kind:"document",module:a,docKey:v.key},label:Pe(v.paths[0]??v.label),icon:v.kind.icon??ve(c,g),noForm:v.model===void 0,dirty:be(i,v),search:v.paths.join(" "),ref:`${c}:${v.paths[0]??v.key}`}))});continue}if(p.length===1){const v=p[0];u.push({id:S,node:{kind:"document",module:a,docKey:v.key},label:fe(o,c),icon:ve(c,g),noForm:v.model===void 0,dirty:be(i,v)});continue}u.push({id:S,node:f,label:fe(o,c),icon:ve(c,g),children:p.map(v=>({id:`${S}/d:${v.key}`,node:{kind:"document",module:a,docKey:v.key},label:v.label,icon:ve(c,g),noForm:v.model===void 0,dirty:be(i,v),search:v.paths.join(" ")}))})}const m=qi(e,i,u,At(i),(c,p)=>fe(o,c,p,s(c)));for(const c of((r=n.panels)==null?void 0:r.call(n,i))??[])m.push({id:`${e}/x:${c.key}`,node:{kind:"panel",module:a,panelKey:c.key},label:c.label,icon:"puzzle"});if(n.advanced){const c=new Set(i.changes.map(g=>g.path)),p=[...i.working].sort((g,S)=>g.path.localeCompare(S.path));m.push({id:`${e}/g:files`,node:{kind:"group",module:a,group:"files"},label:fe(o,"files",p.length),icon:dt.files,children:p.map(g=>({id:`${e}/g:files/f:${g.path}`,node:{kind:"file",module:a,path:g.path},label:g.path,icon:"file",dirty:c.has(g.path)}))})}return m}function Ri(e,i,n,o){const a=i.key,s=n.filter(l=>l.kind.editor==="scriptList").length,d=[];for(const l of n){const u=be(i,l),m=l.paths[0]??l.key,r=je(i,l);if(l.kind.editor!=="scriptList"||l.model===void 0||!r){d.push({id:`${e}/d:${l.key}`,node:{kind:"document",module:a,docKey:l.key},label:Pe(m),icon:l.model===void 0?"warning":"code",noForm:l.model===void 0,dirty:u,search:l.paths.join(" "),ref:`scripts:${m}`});continue}for(const c of r.scripts){const p=c.definition;d.push({id:`${e}/i:${l.key}#${c.key}`,node:{kind:"item",module:a,group:"scripts",docKey:l.key,itemKey:c.key},label:c.label||c.key,icon:p?zt[p.kind]:Ot.scripts,info:p==null?void 0:p.category,noForm:p===void 0,dirty:u,search:`${c.key} ${(p==null?void 0:p.category)??""}`,ref:`scripts:${c.key}`})}if(r.holds==="phases"||Object.keys(r.phases??{}).length>0){const c=o("devStudio.scripts.database","Database scripts");d.push({id:`${e}/d:${l.key}`,node:{kind:"document",module:a,docKey:l.key},label:s>1?`${c} (${Pe(m)})`:c,icon:"database",info:String(Object.values(r.phases??{}).reduce((p,g)=>p+g.length,0)),dirty:u,search:l.paths.join(" "),ref:`scripts:${m}`})}}return{label:fe(o,"scripts",d.length),children:d}}const Ai=new Set(["entities","views","workflows","dataSources","scripts"]),Oe=e=>e.reduce((i,n)=>i+(n.node.kind==="folder"?Oe(n.children??[]):n.ref?1:0),0);function qi(e,i,n,o,a){var g;if($.isEmptyStudioLayout(o))return n;const s=i.key,d=new Set(o.sections.map(S=>S.id)),l=S=>{var f;return(S.ref?(f=o.placement[S.ref])==null?void 0:f.order:void 0)??Number.MAX_SAFE_INTEGER},u=S=>S.some(f=>{var v;return f.ref&&((v=o.placement[f.ref])==null?void 0:v.order)!==void 0})?[...S].sort((f,v)=>l(f)-l(v)):S,m=(S,f,v,y,b)=>{var z;const M=o.folders.filter(K=>K.group===v&&(K.section&&d.has(K.section)?K.section:void 0)===y),N=new Set(M.map(K=>K.id)),k=K=>C=>({...C,id:`${K}${C.id.startsWith(f)?C.id.slice(f.length):`/${C.id}`}`}),x=new Map,w=[];for(const K of b){const C=K.ref?(z=o.placement[K.ref])==null?void 0:z.folder:void 0;C&&N.has(C)?x.set(C,[...x.get(C)??[],K]):w.push(K)}const _=(K,C)=>M.filter(V=>(V.parent&&N.has(V.parent)?V.parent:void 0)===K).map(V=>{const X=`${C}/fo:${V.id}`,A=[..._(V.id,X),...u(x.get(V.id)??[]).map(k(X))];return{id:X,node:{kind:"folder",module:s,folderId:V.id,group:v},label:V.label,icon:"folder",info:String(Oe(A)),children:A}});return[..._(void 0,S),...u(w).map(k(S))]},r=[],c=new Map(o.sections.map(S=>[S.id,[]]));for(const S of n){if(S.node.kind!=="group"||!S.children){r.push(S);continue}const f=S.node.group,v=new Map;for(const b of S.children){const M=b.ref?(g=o.placement[b.ref])==null?void 0:g.section:void 0,N=M&&d.has(M)?M:void 0;v.set(N,[...v.get(N)??[],b])}const y=m(S.id,S.id,f,void 0,v.get(void 0)??[]);r.push({...S,label:p(S,f,y),children:y});for(const b of o.sections){const M=v.get(b.id)??[],N=o.folders.some(w=>w.group===f&&w.section===b.id);if(M.length===0&&!N)continue;const k=`${e}/s:${b.id}/g:${f}`,x=m(k,S.id,f,b.id,M);c.get(b.id).push({...S,id:k,node:{kind:"group",module:s,group:f,section:b.id},label:p(S,f,x),children:x})}}for(const S of o.sections){const f=c.get(S.id)??[];r.push({id:`${e}/s:${S.id}`,node:{kind:"section",module:s,sectionId:S.id},label:S.label,icon:"layers",info:String(f.reduce((v,y)=>v+Oe(y.children??[]),0)),children:f})}return r;function p(S,f,v){return Ai.has(f)||!De(f)?a(f,Oe(v)):S.label}}function Ze(e){const i=e.label||e.id;return i===e.id&&e.id.includes("/")?e.id.slice(e.id.lastIndexOf("/")+1):i}const Ye=e=>e.parentId??(e.id.includes("/")?e.id.slice(0,e.id.lastIndexOf("/")):void 0);function Wi(e,i,n,o){const a=new Map(n.map(m=>[m.id,m]));for(const m of n){let r=Ye(m);for(;r&&!a.has(r);){const c={id:r,workspaceId:e,label:"",derived:!0};a.set(r,c),r=Ye(c)}}const s=[...a.values()],d=m=>{const r=Ye(m);return r&&a.has(r)&&r!==m.id?r:void 0},l=m=>m.sort((r,c)=>r.id===ue?1:c.id===ue?-1:Ze(r).localeCompare(Ze(c))),u=(m,r)=>l(s.filter(c=>d(c)===m)).map(c=>{const p=`${r}/p:${c.id}`;return o(c,p,u(c.id,p))});return u(void 0,i)}function Vi(e){const{t:i}=e,n=i("devStudio.explorer.noPackage","No package"),o=e.workspaces.map(u=>{const m=e.modulesByWs[u.id]??[],r=`w:${u.id}`;return{id:r,node:{kind:"workspace",workspaceId:u.id},label:u.label,icon:Ke(u.icon,"folder"),info:String(m.length),readOnly:u.readOnly,search:u.id,children:Wi(u.id,r,Rt(u.id,e.packagesByWs[u.id],m),(c,p,g)=>{const S=m.filter(f=>(f.packageId??ue)===c.id).sort((f,v)=>f.label.localeCompare(v.label));return{id:p,node:{kind:"package",workspaceId:u.id,packageId:c.id===ue?void 0:c.id},label:c.id===ue?n:Ze(c),icon:Ke(c.icon,"archive"),info:String(S.length),search:c.id,children:[...g,...S.map(f=>{var k;const v=Y(f),y=e.modules[v],b=`${p}/m:${f.id}`,M=y?Bi(b,y,e):void 0,N=y?[...rt(y).map(x=>`${x.entity.name??""} ${lt(x.entity)}`),...y.documents.filter(x=>x.kind.editor==="views").flatMap(x=>le(y,x).map(w=>`${w.key} ${w.label}`))]:[];return{id:b,node:{kind:"module",module:{workspaceId:f.workspaceId,id:f.id}},label:f.label,icon:Ke(f.icon,"box"),info:f.version,readOnly:f.readOnly,shadowedBy:f.shadowedBy,dirty:y==null?void 0:y.dirty,issues:(k=e.issueCounts)==null?void 0:k[v],search:[f.id,f.description??"",f.search??"",...N].join(" "),children:M}})]}})}});if(e.templates){const u=new Map;for(const c of e.workspaces)for(const p of e.modulesByWs[c.id]??[])u.has(p.id)||u.set(p.id,p);const m=new Map;for(const c of e.templates){const p=c.category??"";m.set(p,[...m.get(p)??[],c])}const r=c=>{var p,g;return((p=c.translations.en)==null?void 0:p.name)??((g=Object.values(c.translations)[0])==null?void 0:g.name)??c.id};o.push({id:ze,node:{kind:"templates"},label:i("devStudio.tree.templates","Templates"),icon:"layers",info:String(e.templates.length),children:[...m.entries()].sort(([c],[p])=>c.localeCompare(p)).map(([c,p])=>{const g=`${ze}/c:${c}`;return{id:g,node:{kind:"category",category:c},label:c||i("devStudio.explorer.noCategory","Other"),icon:"folder",info:String(p.length),children:[...p].sort((S,f)=>(S.sortOrder??0)-(f.sortOrder??0)||r(S).localeCompare(r(f))).map(S=>{const f=`${g}/t:${S.id}`;return{id:f,node:{kind:"template",templateId:S.id},label:r(S),icon:Ke(S.icon,"layers"),info:String(S.modules.length),readOnly:S.readOnly,search:`${S.id} ${(S.tags??[]).join(" ")}`,children:S.modules.map(v=>{const y=u.get(v.moduleId);return{id:`${f}/m:${v.moduleId}`,node:{kind:"templateModule",templateId:S.id,moduleId:v.moduleId,target:y?{workspaceId:y.workspaceId,id:y.id}:void 0},label:(y==null?void 0:y.label)??v.moduleId,icon:"box",info:v.required?i("devStudio.template.required","required"):void 0,missing:!y,search:v.moduleId}})}})}})})}const a=new Map,s=new Map,d=new Map,l=(u,m,r=0)=>{for(const c of u){c.depth=r,a.set(c.id,c),m&&s.set(c.id,m);const p=Lt(c.node);d.has(p)||d.set(p,c.id),c.children&&l(c.children,c.id,r+1)}};return l(o),{rows:o,byId:a,parentOf:s,rowOfNode:d}}function wt(e,i){const n=[];let o=i;for(;o;){const a=e.byId.get(o);if(!a)break;n.unshift(a),o=e.parentOf.get(o)}return n}const Qe=(e,i)=>e.rowOfNode.get(Lt(i));function $e(e){return"module"in e?e.module:void 0}function Ji(e,i){var o;const n="module"in e?i.modules[Y(e.module)]:void 0;switch(e.kind){case"module":return n!=null&&n.documents.some(a=>a.kind.editor==="manifest")?{kind:"manifest",module:e.module}:void 0;case"entity":return{kind:"entity",module:e.module,docKey:e.docKey,index:e.index};case"item":{const a=n&&me(n,e.docKey),s=a&&le(n,a).find(d=>d.key===e.itemKey);return(s==null?void 0:s.definition)!==void 0||i.advanced?{...e}:void 0}case"document":{const a=n&&me(n,e.docKey);return(a==null?void 0:a.model)!==void 0?{kind:"document",module:e.module,docKey:e.docKey}:a&&i.advanced?{kind:"file",module:e.module,path:a.paths[0]}:void 0}case"panel":return{kind:"panel",module:e.module,panelKey:e.panelKey};case"file":return{kind:"file",module:e.module,path:e.path};case"package":{const a=(o=i.packages)==null?void 0:o.find(s=>s.id===e.packageId);return a&&!a.derived?{kind:"package",pkg:a}:void 0}case"template":return{kind:"template",templateId:e.templateId};default:return}}function _t(e){switch(e.kind){case"manifest":case"problems":case"history":return{kind:"module",module:e.module};case"entity":return{kind:"entity",module:e.module,docKey:e.docKey,index:e.index};case"item":return{...e};case"document":return{kind:"document",module:e.module,docKey:e.docKey};case"panel":return{kind:"panel",module:e.module,panelKey:e.panelKey};case"file":return{kind:"file",module:e.module,path:e.path};case"package":return{kind:"package",workspaceId:e.pkg.workspaceId,packageId:e.pkg.id};case"template":return e.templateId?{kind:"template",templateId:e.templateId}:void 0}}const Ui=/^\/(?:[A-Za-z]+\/)?(\d+)(?:\/|$)/;function qt(e,i){const n=e.key,o=i.path?e.documents.find(l=>l.paths.includes(i.path)):void 0;if(!o)return{kind:"module",module:n};const a=Pt(o),s=o.paths.length===1?Ui.exec(i.pointer??""):null,d=s?Number(s[1]):-1;if(a==="entities"){const l=ie(e,o);return Array.isArray(l)&&d>=0&&d<l.length?{kind:"entity",module:n,docKey:o.key,index:d}:{kind:"group",module:n,group:a}}if(a==="scripts"&&o.kind.editor==="scriptList"){const l=d>=0?le(e,o)[d]:void 0;return l?{kind:"item",module:n,group:"scripts",docKey:o.key,itemKey:l.key}:{kind:"document",module:n,docKey:o.key}}if(Dt(a)){const l=d>=0?le(e,o)[d]:void 0;return l?{kind:"item",module:n,group:a,docKey:o.key,itemKey:l.key}:{kind:"group",module:n,group:a}}return a?{kind:"document",module:n,docKey:o.key}:o.kind.editor==="manifest"?{kind:"module",module:n}:{kind:"file",module:n,path:o.paths[0]}}function mt(e,i){switch(i){case"frontend":return e("devStudio.scripts.kind.frontend","Frontend");case"backend":return e("devStudio.scripts.kind.backend","Backend");case"noCode":return e("devStudio.scripts.kind.noCode","No-code");case"sql":return e("devStudio.scripts.kind.sql","SQL")}}const Gi=(e,i)=>{switch(i){case"frontend":return e("devStudio.scripts.hint.frontend","TypeScript or JavaScript run in the browser.");case"backend":return e("devStudio.scripts.hint.backend","C# or JavaScript run on the server.");case"noCode":return e("devStudio.scripts.hint.noCode","Steps over the app data, set up without code.");case"sql":return e("devStudio.scripts.hint.sql","A query or procedure run in the database.")}},Wt={typescript:"TypeScript",javascript:"JavaScript",csharp:"C#",sql:"SQL"},Hi=e=>{const i=(e??"").toLowerCase();return i.startsWith("csharp")||i==="c#"?"csharp":i.endsWith("sql")?"sql":i==="typescript"||i==="javascript"?i:"plaintext"};function Vt(e,i){var o;const n=e.documents.flatMap(a=>{var s;return(((s=je(e,a))==null?void 0:s.scripts)??[]).map(d=>{var l;return(l=d.definition)==null?void 0:l.category})});return[...new Set([...((o=i.scripts)==null?void 0:o.categories)??[],...n])].filter(a=>!!a).sort((a,s)=>a.localeCompare(s))}function Jt({value:e,onChange:i,categories:n,readOnly:o,testId:a}){const{t:s}=h.useNiceTranslation(),d=n.filter(l=>l!==e).slice(0,12);return t.jsxs("div",{className:"nice-development-studio__script-category",children:[t.jsx(h.NiceTextInput,{label:s("devStudio.scripts.category","Category"),value:e,onChange:i,readOnly:o,size:"sm","data-testid":a}),!o&&d.length>0&&t.jsx("div",{className:"nice-development-studio__chips",children:d.map(l=>t.jsx(h.NiceButton,{size:"xs",variant:"ghost",onClick:()=>i(l),children:l},l))})]})}function Yi({value:e,onChange:i,readOnly:n}){const{t:o}=h.useNiceTranslation(),a=(s,d)=>i(e.map((l,u)=>u===s?{...l,...d}:l));return t.jsxs("fieldset",{className:"nice-development-studio__script-params",children:[t.jsx("legend",{children:o("devStudio.scripts.parameters","Parameters")}),e.map((s,d)=>t.jsxs("div",{className:"nice-development-studio__script-param",children:[t.jsx(h.NiceTextInput,{label:o("devStudio.scripts.param.name","Name"),labelPlacement:"inside",value:s.name,onChange:l=>a(d,{name:l}),readOnly:n,size:"sm"}),t.jsx(h.NiceTextInput,{label:o("devStudio.scripts.param.type","Type"),labelPlacement:"inside",value:s.type??"",onChange:l=>a(d,{type:l||void 0}),readOnly:n,size:"sm"}),t.jsx(h.NiceTextInput,{label:o("devStudio.scripts.param.description","Description"),labelPlacement:"inside",value:s.description??"",onChange:l=>a(d,{description:l||void 0}),readOnly:n,size:"sm"}),!n&&t.jsx(h.NiceButton,{size:"sm",variant:"ghost","aria-label":o("devStudio.scripts.param.remove","Remove parameter"),onClick:()=>i(e.filter((l,u)=>u!==d)),children:t.jsx(h.NiceIcon,{name:"trash",size:14})})]},d)),!n&&t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:t.jsx(h.NiceIcon,{name:"plus",size:14}),onClick:()=>i([...e,{name:`arg${e.length+1}`,type:"string"}]),children:o("devStudio.scripts.param.add","Add parameter")})]})}function Qi({module:e,doc:i,item:n,preset:o,session:a,readOnly:s,scriptRunner:d,scriptIo:l,onRenamed:u}){var x,w;const{t:m}=h.useNiceTranslation(),r=n.definition,c=j.useMemo(()=>Vt(e,o),[e,o]);if(!r)return null;const p=le(e,i),g=_=>{const z={...r,..._},K=z.name&&!p.some(V=>V!==n&&V.key===z.name)?z.name:n.key,C={...n,key:K,label:z.displayName||z.name||n.label,definition:z};a.setDraft(e.key,i.key,ut(e,i,p.map(V=>V.key===n.key?C:V))),K!==n.key&&u(K)},S=_=>{if(_===r.kind)return;const z=$.studioScriptLanguages(_),K=r.language&&z.includes(r.language)?r.language:z[0],C=$.newStudioScript({kind:_,name:r.name,language:K});g({kind:_,language:K,steps:_==="noCode"?r.steps??[]:void 0,source:_==="noCode"?void 0:r.source??C.source})},f=((x=o.scripts)==null?void 0:x.kinds)??$.NICE_STUDIO_SCRIPT_KINDS,v=$.studioScriptLanguages(r.kind),y=(w=o.scripts)==null?void 0:w.triggers,b=e.documents.flatMap(_=>{var z;return((z=je(e,_))==null?void 0:z.scripts)??[]}).map(_=>_.key).filter(_=>_!==n.key),M=e.documents.filter(_=>_.kind.editor==="dataSources").flatMap(_=>ie(e,_)??[]).map(_=>_.key),N=r.sourcePath?e.documents.find(_=>_.paths.includes(r.sourcePath)):void 0;let k;return r.kind==="noCode"?k=t.jsx(h.NiceNoCodeScriptEditor,{value:{parameters:r.parameters,steps:r.steps??[]},onChange:_=>g({steps:_.steps}),dataSources:M,scripts:b,io:l,readOnly:s}):r.sourcePath&&r.source===void 0?k=t.jsxs("p",{className:"nice-development-studio__muted",children:[m("devStudio.scripts.sourcePath","The code is in {path}.").replace("{path}",r.sourcePath),N?"":` ${m("devStudio.scripts.sourceMissing","The module has no such file.")}`]}):d&&r.kind==="frontend"&&r.language==="javascript"?k=t.jsx(h.NiceScriptRunner,{...d,value:r.source??"",onChange:_=>g({source:_})}):k=t.jsx(h.NiceSimpleCodeEditor,{value:r.source??"",onChange:_=>g({source:_}),language:Hi(r.language),height:"100%",lineNumbers:!0,readOnly:s}),t.jsxs("div",{className:"nice-development-studio__script","data-testid":"studio-script-editor",children:[t.jsxs("div",{className:"nice-development-studio__script-meta",children:[t.jsx(h.NiceTextInput,{label:m("devStudio.scripts.name","Name"),value:r.name,onChange:_=>g({name:_}),readOnly:s,size:"sm","data-testid":"studio-script-name"}),t.jsx(h.NiceTextInput,{label:m("devStudio.scripts.displayName","Display name"),value:r.displayName??"",onChange:_=>g({displayName:_||void 0}),readOnly:s,size:"sm"}),t.jsx(h.NiceSelect,{label:m("devStudio.scripts.kind","Kind"),value:r.kind,options:f.map(_=>({value:_,label:mt(m,_)})),onChange:_=>S(String(_)),disabled:s,size:"sm"}),v.length>0&&t.jsx(h.NiceSelect,{label:m("devStudio.scripts.language","Language"),value:r.language??v[0],options:[...new Set([...v,...r.language?[r.language]:[]])].map(_=>({value:_,label:Wt[_]??_})),onChange:_=>g({language:String(_)}),disabled:s,size:"sm"}),t.jsx(Jt,{value:r.category??"",onChange:_=>g({category:_||void 0}),categories:c,readOnly:s}),y&&y.length>0?t.jsx(h.NiceSelect,{label:m("devStudio.scripts.trigger","Runs on"),value:r.trigger??"",options:[{value:"",label:m("devStudio.scripts.trigger.none","When called")},...y.map(_=>({value:_.id,label:_.label}))],onChange:_=>g({trigger:String(_)||void 0}),disabled:s,size:"sm"}):t.jsx(h.NiceTextInput,{label:m("devStudio.scripts.trigger","Runs on"),value:r.trigger??"",onChange:_=>g({trigger:_||void 0}),readOnly:s,size:"sm"}),r.kind!=="noCode"&&t.jsx(h.NiceTextInput,{label:m("devStudio.scripts.returnType","Returns"),value:r.returnType??"",onChange:_=>g({returnType:_||void 0}),readOnly:s,size:"sm"}),t.jsx(h.NiceTextArea,{label:m("devStudio.scripts.description","Description"),value:r.description??"",onChange:_=>g({description:_||void 0}),readOnly:s,rows:3}),t.jsx(Yi,{value:r.parameters??[],onChange:_=>g({parameters:_}),readOnly:s})]}),t.jsx("div",{className:"nice-development-studio__script-body",children:k})]})}function Xi({value:e,onChange:i,preset:n,readOnly:o}){var S;const{t:a}=h.useNiceTranslation(),s=e.phases??{},d=Object.keys(s),[l,u]=j.useState(d[0]??""),m=d.includes(l)?l:d[0]??"",r=(((S=n.scripts)==null?void 0:S.phases)??$.NICE_STUDIO_SCRIPT_PHASES).filter(f=>!d.includes(f)),c=f=>i({...e,phases:f}),p=s[m]??[],g=f=>c({...s,[m]:f});return e.holds==="scripts"?t.jsx("p",{className:"nice-development-studio__muted",children:a("devStudio.scripts.noPhases","This file holds named scripts only.")}):t.jsxs("div",{className:"nice-development-studio__phases","data-testid":"studio-script-phases",children:[t.jsxs("div",{className:"nice-development-studio__phases-bar",children:[d.map(f=>t.jsx(h.NiceButton,{size:"sm",variant:f===m?"primary":"ghost","aria-pressed":f===m,onClick:()=>u(f),children:`${f} (${s[f].length})`},f)),!o&&r.length>0&&t.jsx(h.NiceSelect,{"aria-label":a("devStudio.scripts.addPhase","Add phase"),placeholder:a("devStudio.scripts.addPhase","Add phase"),value:"",options:r,onChange:f=>{const v=String(f);v&&(c({...s,[v]:[]}),u(v))},size:"sm"}),!o&&m&&t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:t.jsx(h.NiceIcon,{name:"trash",size:14}),onClick:()=>{const f={...s};delete f[m],c(f)},children:a("devStudio.scripts.removePhase","Remove phase")})]}),m?t.jsx("ol",{className:"nice-development-studio__statements",children:p.map((f,v)=>t.jsxs("li",{className:"nice-development-studio__statement",children:[t.jsx(h.NiceSimpleCodeEditor,{value:f,onChange:y=>g(p.map((b,M)=>M===v?y:b)),language:"sql",height:Math.min(240,28+20*(f.split(`
|
|
6
|
+
`).length||1)),readOnly:o}),!o&&t.jsx(h.NiceButton,{size:"sm",variant:"ghost","aria-label":a("devStudio.scripts.removeStatement","Remove statement"),onClick:()=>g(p.filter((y,b)=>b!==v)),children:t.jsx(h.NiceIcon,{name:"trash",size:14})})]},v))}):t.jsx("p",{className:"nice-development-studio__muted",children:a("devStudio.scripts.noPhase","No phases yet: add one to run SQL when the module is installed.")}),!o&&m&&t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:t.jsx(h.NiceIcon,{name:"plus",size:14}),onClick:()=>g([...p,""]),children:a("devStudio.scripts.addStatement","Add statement")})]})}function Ut(e,i){var s;const n=i.kinds.find(d=>d.editor==="scriptList"),o=n&&((s=i.newFile)==null?void 0:s.call(i,n.id,{key:e.key,files:e.working,documents:e.documents}));if(!n||!o||e.working.some(d=>d.path===o.path))return;const a={moduleId:e.key.id,files:e.working,locales:i.locales??[]};try{return{kind:n,file:o,model:n.decode([o],a),ctx:a}}catch{return}}function Gt(e,i,n,o){var g,S,f;const a=e.key,s=o.choice==="phase",d=v=>!!v&&(s?v.holds!=="scripts":v.holds!=="phases"),l=e.documents.find(v=>v.kind.editor==="scriptList"&&v.model!==void 0&&d(je(e,v))),u=v=>{if(s){const k=o.phase||"postInstall",x={...v.phases??{}};x[k]=[...x[k]??[],o.name?`-- ${o.name}
|
|
7
|
+
`:""];const w=v.holds==="scripts"&&v.scripts.length===0?"phases":v.holds;return{model:{...v,phases:x,...w?{holds:w}:{}},screen:_=>({kind:"document",module:a,docKey:_})}}const y=$.newStudioScript({kind:o.choice,name:o.name,language:o.language,category:o.category,trigger:o.trigger});let b=y.name;for(let k=2;v.scripts.some(x=>x.key===b);k++)b=`${y.name}${k}`;const M={...y,name:b},N={key:b,label:M.displayName||b,definition:M,source:{}};return{model:{...v,scripts:[...v.scripts,N]},screen:k=>({kind:"item",module:a,group:"scripts",docKey:k,itemKey:b})}};if(l){const v=u(je(e,l)??{scripts:[]});return n.setDraft(a,l.key,v.model),v.screen(l.key)}const m=Ut(e,i);if(!m)return;const r=u(m.model),{path:c}=m.file,p=(g=m.kind.encode(r.model,[m.file],m.ctx).files.find(v=>v.path===c))==null?void 0:g.text;if(p!==void 0)return n.setRaw(a,c,p),r.screen(`${m.kind.id}:${((f=(S=m.kind).group)==null?void 0:f.call(S,c))??c}`)}function Ht(e,i){return e.documents.some(n=>n.kind.editor==="scriptList"&&n.model!==void 0)||Ut(e,i)!==void 0}function Yt({module:e,preset:i,onAdd:n,onClose:o}){var _,z,K;const{t:a}=h.useNiceTranslation(),s=((_=i.scripts)==null?void 0:_.kinds)??$.NICE_STUDIO_SCRIPT_KINDS,d=((z=i.scripts)==null?void 0:z.phases)??$.NICE_STUDIO_SCRIPT_PHASES,[l,u]=j.useState(s[0]??"frontend"),[m,r]=j.useState(""),[c,p]=j.useState(""),[g,S]=j.useState(""),[f,v]=j.useState(void 0),[y,b]=j.useState(d.includes("postInstall")?"postInstall":d[0]),M=j.useMemo(()=>Vt(e,i),[e,i]),N=l==="phase"?[]:$.studioScriptLanguages(l),k=l==="phase"||!!m.trim(),x=()=>{k&&(o(),n({choice:l,name:m.trim(),category:c.trim()||void 0,trigger:g||void 0,language:f&&N.includes(f)?f:void 0,phase:y}))},w=[...s.map(C=>({id:C,icon:zt[C],label:mt(a,C),hint:Gi(a,C)})),{id:"phase",icon:"database",label:a("devStudio.scripts.kind.phase","Database script"),hint:a("devStudio.scripts.hint.phase","SQL run when the module is installed or removed.")}];return t.jsx(h.NiceModal,{open:!0,onClose:o,title:a("devStudio.scripts.add","Add script"),footer:t.jsxs(t.Fragment,{children:[t.jsx(h.NiceButton,{variant:"ghost",onClick:o,children:a("devStudio.cancel","Cancel")}),t.jsx(h.NiceButton,{variant:"primary",disabled:!k,onClick:x,"data-testid":"studio-script-add-ok",children:a("devStudio.scripts.create","Create")})]}),children:t.jsxs("div",{className:"nice-development-studio__form",children:[t.jsx("div",{className:"nice-development-studio__script-kinds",children:w.map(C=>t.jsxs("button",{type:"button","aria-pressed":C.id===l,className:`nice-development-studio__script-kind${C.id===l?" nice-development-studio__script-kind--active":""}`,onClick:()=>u(C.id),"data-testid":`studio-script-kind-${C.id}`,children:[t.jsx(h.NiceIcon,{name:C.icon,size:20}),t.jsx("strong",{children:C.label}),t.jsx("span",{children:C.hint})]},C.id))}),l==="phase"?t.jsxs(t.Fragment,{children:[t.jsx(h.NiceSelect,{label:a("devStudio.scripts.phase","Phase"),value:y,options:[...d],onChange:C=>b(String(C)),size:"sm"}),t.jsx(h.NiceTextInput,{label:a("devStudio.scripts.comment","What it does"),value:m,onChange:r,size:"sm"})]}):t.jsxs(t.Fragment,{children:[t.jsx(h.NiceTextInput,{label:a("devStudio.scripts.name","Name"),value:m,onChange:r,onKeyDown:C=>{C.key==="Enter"&&x()},size:"sm","data-testid":"studio-script-add-name"}),N.length>1&&t.jsx(h.NiceSelect,{label:a("devStudio.scripts.language","Language"),value:f&&N.includes(f)?f:N[0],options:N.map(C=>({value:C,label:Wt[C]??C})),onChange:C=>v(String(C)),size:"sm"}),t.jsx(Jt,{value:c,onChange:p,categories:M}),((K=i.scripts)==null?void 0:K.triggers)&&i.scripts.triggers.length>0&&t.jsx(h.NiceSelect,{label:a("devStudio.scripts.trigger","Runs on"),value:g,options:[{value:"",label:a("devStudio.scripts.trigger.none","When called")},...i.scripts.triggers.map(C=>({value:C.id,label:C.label}))],onChange:C=>S(String(C)),size:"sm"})]})]})})}function It(e){var m,r;const{module:i,doc:n,preset:o,session:a,locales:s,readOnly:d}=e,l=ie(i,n),u=c=>a.setDraft(i.key,n.key,c);switch(n.kind.editor){case"manifest":return t.jsx(Zi,{...e});case"i18n":{const c=l??{};return t.jsx(at,{value:c,onChange:u,locales:[...new Set([...s,...Object.keys(c)])],allowEditLocales:!0,allowEditKeys:!0,highlightMissing:!0,readOnly:d})}case"permissions":return t.jsx(en,{value:l??{permissions:[],groups:[]},onChange:u,readOnly:d});case"seeds":return t.jsx(sn,{value:l??{seeds:{}},onChange:u,entities:Xe(i),readOnly:d});case"rbac":return t.jsx(h.NiceAccessManager,{value:l,onChange:u,readOnly:d});case"hooks":return t.jsx(h.NiceLifecycleHooksEditor,{triggers:((m=o.hooks)==null?void 0:m.triggers)??[],handlers:(r=o.hooks)==null?void 0:r.handlers,bindings:l??[],onChange:u,groupByTrigger:!0,allowCondition:!0,readOnly:d});case"script":return e.scriptRunner?t.jsx(h.NiceScriptRunner,{...e.scriptRunner,value:String(l??""),onChange:u}):t.jsx(h.NiceSimpleCodeEditor,{value:String(l??""),onChange:u,language:"javascript",height:"100%",lineNumbers:!0,readOnly:d});case"scriptList":return t.jsx(Xi,{value:l??{scripts:[]},onChange:u,preset:o,readOnly:d});case"text":return t.jsx(h.NiceSimpleCodeEditor,{value:String(l??""),onChange:u,height:"100%",lineNumbers:!0,readOnly:d});default:return t.jsx(ot,{value:l,onChange:u,readOnly:d,height:"100%",label:n.label})}}function Zi({module:e,doc:i,preset:n,session:o,readOnly:a,advanced:s}){var M;const{t:d}=h.useNiceTranslation(),l=ie(e,i),u=j.useMemo(()=>l??{},[l]),m=N=>o.setDraft(e.key,i.key,N),r=n.manifestSections,c=j.useMemo(()=>(r??[]).map(N=>$.fitManifestSection(N,u)),[r,u]),p=r??[],g=j.useMemo(()=>new Set(c.flatMap(N=>N.keys)),[c]),S=Object.keys(u).filter(N=>!g.has(N)),[f,v]=j.useState(((M=c[0])==null?void 0:M.section.id)??"__other"),y=c.find(N=>N.section.id===f),b=s?t.jsx(ot,{value:Object.fromEntries(S.map(N=>[N,u[N]])),readOnly:a,label:d("devStudio.manifest.other","Other properties"),onChange:N=>{if(N&&typeof N=="object"&&!Array.isArray(N)){const k=Object.fromEntries(Object.entries(u).filter(([x])=>g.has(x)));m({...k,...N})}}}):t.jsxs("div",{className:"nice-development-studio__note",children:[t.jsx("p",{children:d("devStudio.manifest.kept","These properties have no form here. Saving keeps them exactly as they are; switch to the advanced mode to edit them.")}),t.jsx("ul",{className:"nice-development-studio__chips",children:S.map(N=>t.jsx("li",{className:"nice-development-studio__tag",children:N},N))})]});return t.jsxs("div",{className:"nice-development-studio__sections","data-testid":"studio-manifest-form",children:[t.jsxs("nav",{className:"nice-development-studio__section-nav","aria-label":d("devStudio.manifest.sections","Sections"),children:[c.map(({section:N})=>t.jsx(h.NiceButton,{size:"sm",variant:f===N.id?"primary":"ghost","aria-pressed":f===N.id,onClick:()=>v(N.id),children:N.title},N.id)),S.length>0&&t.jsx(h.NiceButton,{size:"sm",variant:f==="__other"?"primary":"ghost","aria-pressed":f==="__other",onClick:()=>v("__other"),children:`${d("devStudio.manifest.other","Other properties")} (${S.length})`})]}),t.jsx("div",{className:"nice-development-studio__section-body",children:y?t.jsx(Ie,{schema:y.section.schema,fields:y.section.fields,uiSchema:y.section.uiSchema,value:Object.fromEntries(y.keys.filter(N=>N in u).map(N=>[N,u[N]])),onChange:N=>{const k={...u};for(const x of y.keys)N[x]===void 0?delete k[x]:k[x]=N[x];m(k)},readOnly:a}):S.length>0||p.length===0?b:null})]})}function en({value:e,onChange:i,readOnly:n}){const{t:o}=h.useNiceTranslation(),a={code:o("devStudio.permissions.code","Code"),name:o("devStudio.permissions.name","Name"),description:o("devStudio.permissions.description","Description")},s=j.useMemo(()=>{const l={};for(const u of e.groups)for(const m of u.permissions)l[`${u.id}:${m}`]=!0;return l},[e.groups]),d=(l,u)=>{const m=e.permissions[l],r={...m,...u};i({permissions:e.permissions.map((c,p)=>p===l?r:c),groups:u.code!==void 0&&u.code!==m.code?e.groups.map(c=>({...c,permissions:c.permissions.map(p=>p===m.code?r.code:p)})):e.groups})};return t.jsxs("div",{className:"nice-development-studio__permissions",children:[t.jsx("h4",{children:o("devStudio.permissions.codes","Permissions")}),t.jsxs("table",{className:"nice-development-studio__table",children:[t.jsx("thead",{children:t.jsxs("tr",{children:[t.jsx("th",{children:a.code}),t.jsx("th",{children:a.name}),t.jsx("th",{children:a.description}),!n&&t.jsx("th",{"aria-label":o("devStudio.delete","Delete")})]})}),t.jsx("tbody",{children:e.permissions.map((l,u)=>t.jsxs("tr",{children:[["code","name","description"].map(m=>t.jsx("td",{children:t.jsx("input",{className:"nice-development-studio__cell",value:l[m]??"",readOnly:n,"aria-label":`${a[m]} ${l.code}`,onChange:r=>d(u,{[m]:r.target.value})})},m)),!n&&t.jsx("td",{children:t.jsx(h.NiceButton,{size:"sm",variant:"ghost",ariaLabel:`${o("devStudio.delete","Delete")} ${l.code}`,onClick:()=>i({permissions:e.permissions.filter((m,r)=>r!==u),groups:e.groups.map(m=>({...m,permissions:m.permissions.filter(r=>r!==l.code)}))}),children:t.jsx(h.NiceIcon,{name:"trash",size:14})})})]},u))})]}),!n&&t.jsxs("div",{className:"nice-development-studio__row",children:[t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:t.jsx(h.NiceIcon,{name:"plus",size:14}),onClick:()=>i({...e,permissions:[...e.permissions,{code:`New.Permission${e.permissions.length+1}`}]}),children:o("devStudio.permissions.addCode","New permission")}),t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:t.jsx(h.NiceIcon,{name:"plus",size:14}),onClick:()=>i({...e,groups:[...e.groups,{id:`group${e.groups.length+1}`,label:o("devStudio.permissions.newGroup","Group {n}").replace("{n}",String(e.groups.length+1)),permissions:[]}]}),children:o("devStudio.permissions.addGroup","New group")})]}),t.jsx("h4",{children:o("devStudio.permissions.groups","Groups")}),t.jsx(h.NicePermissionMatrix,{roles:e.groups.map(l=>({id:l.id,label:l.label})),actions:e.permissions.map(l=>({id:l.code,label:l.name||l.code})),value:s,readOnly:n,showBulkActions:!0,onChange:l=>i({...e,groups:e.groups.map(u=>({...u,permissions:e.permissions.map(m=>m.code).filter(m=>l[`${u.id}:${m}`]===!0)}))})})]})}const Ct=e=>e===null||typeof e!="object";function tn(e){const i=e.toLowerCase();return/(int|long|decimal|double|float|number|money)/.test(i)?"number":/bool/.test(i)?"boolean":"string"}function nn(e,i){const n={},o=Array.isArray(i==null?void 0:i.fields)?i.fields:[];for(const a of o){const s=String(a.name??"");s&&e.every(d=>Ct(d[s]))&&(n[s]={type:tn(String(a.dataType??a.type??"string")),title:String(a.displayName||s)})}for(const a of e)for(const[s,d]of Object.entries(a))!(s in n)&&e.every(l=>Ct(l[s]))&&(n[s]={type:typeof d=="number"?"number":typeof d=="boolean"?"boolean":"string",title:s});return{type:"object",properties:n}}function sn({value:e,onChange:i,entities:n,readOnly:o}){const{t:a}=h.useNiceTranslation(),s=l=>n.find(u=>u.name===l||u.tableName===l),d=l=>{const u=e[l]??{},m=Object.keys(u);return m.length===0?t.jsx("p",{className:"nice-development-studio__muted",children:a("devStudio.seeds.empty","No rows.")}):t.jsx(h.NiceTabs,{tabs:m.map(r=>{const c=u[r];return{id:r,label:`${r} (${c.length})`,content:t.jsx(nt,{value:c,itemSchema:nn(c,s(r)),title:r,readOnly:o,onChange:p=>{const g=p.length===c.length?p.map((S,f)=>S===c[f]?S:{...c[f],...S}):p;i({...e,[l]:{...u,[r]:g}})}})}})})};return t.jsx(h.NiceTabs,{tabs:[{id:"seeds",label:a("devStudio.seeds.data","Data"),content:d("seeds")},{id:"demo",label:a("devStudio.seeds.demo","Demo data"),content:d("demoSeeds")}]})}function on({module:e,path:i,session:n,readOnly:o}){var r;const{t:a}=h.useNiceTranslation(),[s,d]=j.useState("source"),l=e.changes.find(c=>c.path===i),u=e.documents.filter(c=>c.paths.includes(i)).map(c=>c.key),m=((r=e.files.find(c=>c.path===i))==null?void 0:r.text)??"";return t.jsxs("div",{className:"nice-development-studio__source","data-testid":"studio-file-source",children:[t.jsx("div",{className:"nice-development-studio__row",children:t.jsxs("div",{className:"nice-development-studio__segmented",role:"group","aria-label":a("devStudio.doc.mode","Show"),children:[t.jsx(h.NiceButton,{size:"sm",variant:s==="source"?"primary":"ghost","aria-pressed":s==="source",onClick:()=>d("source"),children:a("devStudio.doc.source","Source")}),t.jsx(h.NiceButton,{size:"sm",variant:s==="changes"?"primary":"ghost","aria-pressed":s==="changes",onClick:()=>d("changes"),children:`${a("devStudio.doc.changes","Changes")}${l?" (1)":""}`})]})}),s==="source"?t.jsx(h.NiceSimpleCodeEditor,{value:e.pending.get(i)??"",language:i.endsWith(".json")?"json":i.endsWith(".js")?"javascript":"plaintext",height:"100%",lineNumbers:!0,readOnly:o,onChange:c=>n.setRaw(e.key,i,$.keepTextFormat(c,e.pending.get(i)),u)}):l?t.jsx(Mt,{before:m,after:l.type==="write"?l.text:""}):t.jsx("p",{className:"nice-development-studio__muted",children:a("devStudio.diff.none","No changes.")})]})}const an=e=>({type:"object",required:["id"],properties:{id:{type:"string",title:e("devStudio.template.id","Id (slug)")},category:{type:"string",title:e("devStudio.template.category","Category")},subCategory:{type:"string",title:e("devStudio.template.subCategory","Subcategory")},parentId:{type:"string",title:e("devStudio.template.parent","Parent template")},icon:{type:"string",title:e("devStudio.template.icon","Icon")},sortOrder:{type:"number",title:e("devStudio.template.sortOrder","Order")},tags:{type:"array",items:{type:"string"},title:e("devStudio.template.tags","Tags")}}});function dn({session:e,template:i,locales:n,extraSchema:o,readOnly:a,onSaved:s,onDeleted:d}){var N;const{t:l}=h.useNiceTranslation(),[u,m]=j.useState(()=>i??{id:"",translations:{[n[0]??"en"]:{name:""}},modules:[]}),[r,c]=j.useState(null),p=a||!!(i!=null&&i.readOnly),g={id:u.id,category:u.category,subCategory:u.subCategory,parentId:u.parentId,icon:u.icon,sortOrder:u.sortOrder,tags:u.tags},S=Object.fromEntries(Object.entries(u.translations).map(([k,x])=>[k,{name:x.name,description:x.description??""}])),f=j.useMemo(()=>e.workspaces.map(k=>{const x=e.modulesByWs[k.id]??[],w=[...new Set(x.map(_=>_.packageId??""))].sort();return{id:`w:${k.id}`,label:k.label,kind:"workspace",children:w.map(_=>({id:`w:${k.id}/p:${_}`,label:_||l("devStudio.explorer.noPackage","No package"),kind:"package",children:x.filter(z=>(z.packageId??"")===_).map(z=>({id:`m:${z.id}`,label:z.label,kind:"module"}))}))}}),[e.workspaces,e.modulesByWs,l]),v=j.useMemo(()=>{const k=new Map;for(const x of Object.values(e.modulesByWs))for(const w of x)k.set(w.id,w.label);return k},[e.modulesByWs]),y=k=>m({...u,modules:k}),b=(k,x)=>{const w=[...u.modules],[_]=w.splice(k,1);w.splice(k+x,0,_),y(w)},M=[{field:"label",header:l("devStudio.explorer.name","Name")}];return t.jsxs("div",{className:"nice-development-studio__template","data-testid":"studio-template-editor",children:[t.jsxs("div",{className:"nice-development-studio__doc-bar",children:[t.jsx(h.NiceIcon,{name:"layers",size:14}),t.jsx("strong",{className:"nice-development-studio__doc-title",children:i?((N=u.translations.en)==null?void 0:N.name)||u.id:l("devStudio.template.new","New template")}),t.jsx("span",{className:"nice-development-studio__spacer"}),!p&&t.jsx(h.NiceButton,{size:"sm",variant:"primary",disabled:!u.id.trim(),onClick:async()=>{c(null);const k=await e.saveTemplate({...u,id:u.id.trim()},i==null?void 0:i.id);k?s==null||s(k):c(l("devStudio.template.saveFailed","The template could not be saved; see the output panel."))},children:l("devStudio.save","Save")}),!p&&i&&t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:t.jsx(h.NiceIcon,{name:"trash",size:14}),onClick:async()=>{await e.deleteTemplate(i.id)&&(d==null||d())},children:l("devStudio.delete","Delete")})]}),r&&t.jsx("p",{className:"nice-development-studio__error",role:"alert",children:r}),t.jsxs("div",{className:"nice-development-studio__columns",children:[t.jsxs("section",{children:[t.jsx("h4",{children:l("devStudio.template.basics","Template")}),t.jsx(Ie,{schema:an(l),value:g,readOnly:p,onChange:k=>m({...u,id:String(k.id??""),category:k.category||void 0,subCategory:k.subCategory||void 0,parentId:k.parentId||void 0,icon:k.icon||void 0,sortOrder:typeof k.sortOrder=="number"?k.sortOrder:void 0,tags:Array.isArray(k.tags)?k.tags:void 0})}),o&&t.jsx(Ie,{schema:o,value:u.extra??{},readOnly:p,onChange:k=>m({...u,extra:k})}),t.jsx("h4",{children:l("devStudio.template.translations","Name and description")}),t.jsx(at,{value:S,locales:[...new Set([...n,...Object.keys(S)])],allowEditLocales:!0,readOnly:p,onChange:k=>m({...u,translations:Object.fromEntries(Object.entries(k).map(([x,w])=>[x,{name:w.name??"",...w.description?{description:w.description}:{}}]))})})]}),t.jsxs("section",{children:[t.jsx("h4",{children:l("devStudio.template.modules","Modules")}),t.jsx(h.NiceTreeGrid,{data:f,nested:!0,keyField:"id",childrenField:"children",columns:M,sortable:!1,compact:!0,checkable:!0,checkStrategy:"leaves",isRowCheckable:k=>k.kind!=="workspace",isRowDisabled:()=>p,checkedKeys:u.modules.map(k=>`m:${k.moduleId}`),onCheckedChange:k=>{const x=k.filter(z=>z.startsWith("m:")).map(z=>z.slice(2)),w=u.modules.filter(z=>x.includes(z.moduleId)),_=x.filter(z=>!w.some(K=>K.moduleId===z)).map(z=>({moduleId:z}));y([...w,..._])},checkedSummary:k=>l("devStudio.template.summary","{count} modules · {required} required").replace("{count}",String(k.checked)).replace("{required}",String(u.modules.filter(x=>x.required).length)),searchable:!0,searchFields:["label"],virtualScroll:!0,height:320,"aria-label":l("devStudio.template.modules","Modules")}),t.jsxs("table",{className:"nice-development-studio__table",children:[t.jsx("thead",{children:t.jsxs("tr",{children:[t.jsx("th",{children:l("devStudio.template.module","Module")}),t.jsx("th",{children:l("devStudio.template.required","required")}),t.jsx("th",{children:l("devStudio.template.condition","Condition")}),!p&&t.jsx("th",{"aria-label":l("devStudio.template.order","Order")})]})}),t.jsx("tbody",{children:u.modules.map((k,x)=>t.jsxs("tr",{children:[t.jsx("td",{children:v.get(k.moduleId)??k.moduleId}),t.jsx("td",{children:t.jsx("input",{type:"checkbox",checked:!!k.required,disabled:p,"aria-label":`${l("devStudio.template.required","required")} ${k.moduleId}`,onChange:w=>y(u.modules.map((_,z)=>z===x?{..._,required:w.target.checked}:_))})}),t.jsx("td",{children:t.jsx("input",{className:"nice-development-studio__cell",value:k.condition??"",readOnly:p,"aria-label":`${l("devStudio.template.condition","Condition")} ${k.moduleId}`,onChange:w=>y(u.modules.map((_,z)=>z===x?{..._,condition:w.target.value||void 0}:_))})}),!p&&t.jsxs("td",{className:"nice-development-studio__nowrap",children:[t.jsx(h.NiceButton,{size:"sm",variant:"ghost",disabled:x===0,ariaLabel:l("devStudio.template.up","Move up"),onClick:()=>b(x,-1),children:t.jsx(h.NiceIcon,{name:"chevron-up",size:12})}),t.jsx(h.NiceButton,{size:"sm",variant:"ghost",disabled:x===u.modules.length-1,ariaLabel:l("devStudio.template.down","Move down"),onClick:()=>b(x,1),children:t.jsx(h.NiceIcon,{name:"chevron-down",size:12})})]})]},k.moduleId))})]})]})]})]})}function rn({session:e,pkg:i,readOnly:n,onNewModule:o,onOpenModule:a}){const{t:s}=h.useNiceTranslation(),[d,l]=j.useState({id:i.id,label:i.label,description:i.description,icon:i.icon}),u=(e.modulesByWs[i.workspaceId]??[]).filter(r=>r.packageId===i.id),m=!n&&!i.derived&&!i.readOnly;return t.jsxs("div",{className:"nice-development-studio__template","data-testid":"studio-package-editor",children:[t.jsxs("div",{className:"nice-development-studio__doc-bar",children:[t.jsx(h.NiceIcon,{name:"archive",size:14}),t.jsx("strong",{className:"nice-development-studio__doc-title",children:i.label||i.id}),t.jsx("span",{className:"nice-development-studio__spacer"}),!n&&t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:t.jsx(h.NiceIcon,{name:"plus",size:14}),onClick:o,children:s("devStudio.package.newModule","New module here")}),m&&t.jsx(h.NiceButton,{size:"sm",variant:"primary",onClick:()=>void e.savePackage({...i,id:String(d.id??i.id),label:String(d.label??""),description:d.description||void 0,icon:d.icon||void 0}),children:s("devStudio.save","Save")})]}),i.derived?t.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.")}):t.jsx(Ie,{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:d,readOnly:!m,onChange:r=>l(r)}),t.jsx("h4",{children:s("devStudio.template.modules","Modules")}),t.jsxs("ul",{className:"nice-development-studio__list",children:[u.map(r=>t.jsxs("li",{children:[t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:t.jsx(h.NiceIcon,{name:"box",size:14}),onClick:()=>a(r.id),children:r.label}),r.description&&t.jsx("span",{className:"nice-development-studio__muted",children:r.description})]},r.id)),u.length===0&&t.jsx("li",{className:"nice-development-studio__muted",children:s("devStudio.explorer.empty","No modules.")})]})]})}const ln=e=>"module"in e?e.module:void 0;function cn(e){const{screen:i,crumbs:n,session:o,readOnly:a,tutorialButton:s,onBack:d,onSave:l}=e,{t:u}=h.useNiceTranslation(),m=ln(i),r=m?o.modules[Y(m)]:void 0,c=a(m),p=un(i,r,o);return t.jsxs("div",{className:"nice-development-studio__edit","data-testid":"studio-edit-screen",children:[t.jsxs("header",{className:"nice-development-studio__edit-header",children:[t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:t.jsx(h.NiceIcon,{name:"arrow-left",size:14}),onClick:d,"data-testid":"studio-back",children:u("devStudio.edit.back","Back")}),t.jsx(h.NiceBreadcrumb,{className:"nice-development-studio__crumbs",size:"sm",separator:"›",items:n}),t.jsx("span",{className:"nice-development-studio__spacer"}),p&&!c&&t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:t.jsx(h.NiceIcon,{name:"trash",size:14}),onClick:()=>{p(),d()},children:u("devStudio.delete","Delete")}),r&&t.jsxs(t.Fragment,{children:[t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:t.jsx(h.NiceIcon,{name:"check",size:14}),onClick:()=>void o.validate(r.key),children:u("devStudio.validate","Validate")}),!c&&t.jsxs(t.Fragment,{children:[t.jsx(h.NiceButton,{size:"sm",variant:"ghost",disabled:!r.dirty,onClick:()=>o.discard(r.key),children:u("devStudio.discard","Discard changes")}),t.jsx(h.NiceButton,{size:"sm",variant:"primary",disabled:!r.dirty,onClick:()=>l(r.key),"data-tour":"devstudio-save",children:r.dirty?u("devStudio.saveCount","Save ({count})").replace("{count}",String(r.changes.length)):u("devStudio.save","Save")})]})]}),s]}),t.jsx("div",{className:"nice-development-studio__edit-body",children:t.jsx(mn,{...e,module:r,readOnlyHere:c})})]})}function un(e,i,n){if(!i||e.kind!=="entity"&&e.kind!=="item")return;const o=me(i,e.docKey);if(!o)return;if(e.kind==="entity"){const s=ie(i,o);return Array.isArray(s)?()=>n.setDraft(i.key,o.key,ct(s,e.index,null)):void 0}if(e.group==="dataSources"){const s=ie(i,o)??[];return()=>n.setDraft(i.key,o.key,s.filter(d=>d.key!==e.itemKey))}const a=le(i,o);return()=>n.setDraft(i.key,o.key,ut(i,o,Bt(a,e.itemKey,null)))}function ge(){const{t:e}=h.useNiceTranslation();return t.jsx("p",{className:"nice-development-studio__muted",children:e("devStudio.edit.gone","This is no longer in the module.")})}function mn(e){var r,c,p,g,S;const{screen:i,module:n,session:o,preset:a,provider:s,locales:d,advanced:l,readOnlyHere:u}=e,{t:m}=h.useNiceTranslation();if(i.kind==="package")return t.jsx(rn,{session:o,pkg:i.pkg,readOnly:e.readOnly(),onNewModule:()=>e.onNewModule({workspaceId:i.pkg.workspaceId,packageId:i.pkg.id}),onOpenModule:f=>e.onReveal({kind:"module",module:{workspaceId:i.pkg.workspaceId,id:f}})});if(i.kind==="template"){const f=i.templateId?(r=o.templates)==null?void 0:r.find(v=>v.id===i.templateId):void 0;return t.jsx(dn,{session:o,template:f,locales:d,extraSchema:a.templateSchema,readOnly:e.readOnly(),onSaved:v=>{v.id!==i.templateId&&e.onScreen({kind:"template",templateId:v.id})},onDeleted:e.onBack},i.templateId??"new")}if(!n)return t.jsx("p",{className:"nice-development-studio__muted",children:m("devStudio.loading","Loading…")});switch(i.kind){case"manifest":{const f=n.documents.find(v=>v.kind.editor==="manifest");return f?t.jsx(It,{module:n,doc:f,preset:a,session:o,locales:d,readOnly:u,advanced:l,scriptRunner:e.scriptRunner}):t.jsx(ge,{})}case"entity":{const f=me(n,i.docKey),v=f?ie(n,f):void 0,y=Array.isArray(v)?v[i.index]:void 0;return!f||!v||!y?t.jsx(ge,{}):t.jsx(st,{value:y,onChange:b=>o.setDraft(n.key,f.key,ct(v,i.index,b)),entityMetaSchema:(c=a.entities)==null?void 0:c.entityMetaSchema,fieldSchema:(p=a.entities)==null?void 0:p.fieldSchema,fieldsKey:(g=a.entities)==null?void 0:g.fieldsKey,readOnly:u,"data-testid":"studio-entity-form"})}case"item":return t.jsx(pn,{...e,screen:i,module:n});case"document":{const f=me(n,i.docKey);return f?t.jsx(It,{module:n,doc:f,preset:a,session:o,locales:d,readOnly:u,advanced:l,scriptRunner:e.scriptRunner}):t.jsx(ge,{})}case"panel":{const f=(S=e.modulePanels)==null?void 0:S.call(e,{module:n.key,files:n.working,dirty:n.dirty}).find(v=>v.key===i.panelKey);return f?t.jsx(t.Fragment,{children:f.content}):t.jsx(ge,{})}case"file":return n.working.some(f=>f.path===i.path)?t.jsx(on,{module:n,path:i.path,session:o,readOnly:u}):t.jsx(ge,{});case"problems":return t.jsx(hn,{module:n,issues:e.issues(n.key),onReveal:e.onReveal});case"history":return t.jsx(vn,{module:n,provider:s,session:o,readOnly:u})}}function pn({screen:e,module:i,session:n,preset:o,readOnlyHere:a,advanced:s,scriptRunner:d,scriptIo:l,renderViewPreview:u,onScreen:m}){const{t:r}=h.useNiceTranslation(),c=me(i,e.docKey);if(!c)return t.jsx(ge,{});if(e.group==="dataSources"){const y=ie(i,c)??[],b=y.find(M=>M.key===e.itemKey);return b?t.jsx(h.NiceDataSourceBuilder,{value:b,schemas:$.entitiesToSchemas(Xe(i)),onChange:M=>{n.setDraft(i.key,c.key,y.map(N=>N.key===b.key?M:N)),M.key!==b.key&&m({...e,itemKey:M.key})}}):t.jsx(ge,{})}const p=le(i,c),g=p.find(y=>y.key===e.itemKey);if(!g)return t.jsx(ge,{});const S=y=>{n.setDraft(i.key,c.key,ut(i,c,Bt(p,g.key,y))),y.key!==g.key&&m({...e,itemKey:y.key})},f=y=>S({...g,definition:y,label:y.name||g.label,key:y.id&&!p.some(b=>b!==g&&b.key===y.id)?y.id:g.key});if(g.definition===void 0)return s?t.jsxs("div",{className:"nice-development-studio__source",children:[t.jsxs("p",{className:"nice-development-studio__muted",children:[r("devStudio.items.rawReason","The editor does not know this shape, so it is edited as JSON."),g.rawReason?` (${g.rawReason})`:""]}),t.jsx(ot,{value:g.source,readOnly:a,label:g.label,height:"100%",onChange:y=>S({...g,source:y})})]}):t.jsx("p",{className:"nice-development-studio__muted",children:r("devStudio.preview.noDesigner","There is no designer for this kind of entry yet.")});if(e.group==="scripts")return t.jsx(Qi,{module:i,doc:c,item:g,preset:o,session:n,readOnly:a,scriptRunner:d,scriptIo:l==null?void 0:l(i.key),onRenamed:y=>m({...e,itemKey:y})});if(e.group==="workflows")return t.jsx(di.NiceWorkflowDesigner,{workflow:g.definition,onChange:y=>f(y),readOnly:a});const v=t.jsx(h.NiceViewEditor,{value:g.definition,onChange:y=>f(y),entities:Xe(i),dataSourceOptions:i.documents.filter(y=>y.kind.editor==="dataSources").flatMap(y=>ie(i,y)??[]).map(y=>({key:y.key,label:y.label})),height:640});return u?t.jsx(h.NiceTabs,{tabs:[{id:"design",label:r("devStudio.view.design","Design"),content:v},{id:"preview",label:r("devStudio.view.hostPreview","Preview in the app"),content:u({module:i.key,item:g,files:i.working})}]}):v}function hn({module:e,issues:i,onReveal:n}){const{t:o}=h.useNiceTranslation();return i.length===0?t.jsx("p",{className:"nice-development-studio__muted",children:o("devStudio.overview.noProblems","No problems found.")}):t.jsx("ul",{className:"nice-development-studio__issues","data-testid":"studio-problems",children:i.map((a,s)=>t.jsxs("li",{className:`nice-development-studio__issue nice-development-studio__issue--${a.severity}`,children:[t.jsx(h.NiceIcon,{name:a.severity==="error"?"error":a.severity==="warning"?"warning":"info",size:14}),t.jsx("span",{children:Qt(o,a)}),a.path&&t.jsx("span",{className:"nice-development-studio__muted",children:a.path}),t.jsx(h.NiceButton,{size:"sm",variant:"ghost",onClick:()=>n(qt(e,a)),children:o("devStudio.problems.goTo","Go to")})]},s))})}function Qt(e,i){return i.messageKey?Object.entries(i.params??{}).reduce((n,[o,a])=>n.replace(`{${o}}`,String(a)),e(i.messageKey,i.message)):i.message}function vn({module:e,provider:i,session:n,readOnly:o}){const[a,s]=j.useState(null),d=e.key;return j.useEffect(()=>{let l=!0;return i!=null&&i.listRevisions&&i.listRevisions(d).then(u=>{l&&s(u.map(m=>({id:m.id,label:m.label,author:m.author,timestamp:m.timestamp,summary:m.summary})))}).catch(()=>s([])),()=>{l=!1}},[i,d,e.files]),t.jsx(h.NiceRevisionHistory,{revisions:a??[],language:"json",loadContent:i!=null&&i.readRevision?l=>i.readRevision(d,l):void 0,onRollback:i!=null&&i.rollback&&!o?async l=>{await i.rollback(d,l),await n.reload(d)}:void 0})}function fn({prompt:e,onClose:i}){const{t:n}=h.useNiceTranslation(),[o,a]=j.useState(e.initial),s=()=>{o.trim()&&(i(),e.onSubmit(o.trim()))};return t.jsx(h.NiceModal,{open:!0,onClose:i,title:e.title,footer:t.jsxs(t.Fragment,{children:[t.jsx(h.NiceButton,{variant:"ghost",onClick:i,children:n("devStudio.cancel","Cancel")}),t.jsx(h.NiceButton,{variant:"primary",disabled:!o.trim(),onClick:s,children:n("devStudio.ok","OK")})]}),children:t.jsx("div",{className:"nice-development-studio__form",children:t.jsx(h.NiceTextInput,{label:n("devStudio.package.label","Name"),value:o,onChange:a,onKeyDown:d=>{d.key==="Enter"&&s()},"data-testid":"studio-layout-name"})})})}function gn(e,i){const{t:n}=h.useNiceTranslation(),[o,a]=j.useState(null),s=j.useCallback((l,u)=>{var g;const m=e.modules[Y(l)];if(!m)return;const r=$.studioLayoutPath(m.working),c=(g=m.working.find(S=>S.path===r))==null?void 0:g.text,p=u($.parseStudioLayout(c));if($.isEmptyStudioLayout(p)){c!==void 0&&e.deleteFile(l,r);return}e.setRaw(l,r,$.serializeStudioLayout(p,c))},[e]);return{menuFor:j.useCallback(l=>{const u=l.node,m=$e(u),r=m?e.modules[Y(m)]:void 0;if(!m||!r||i(m))return;const c=At(r),p=(y,b,M)=>a({title:y,initial:b,onSubmit:M}),g=n("devStudio.layout.newFolder","New folder"),S=(y,b,M)=>({id:"new-folder",icon:"folder",label:g,onSelect:()=>p(g,"",N=>s(m,k=>$.addStudioFolder(k,{label:N,group:y,parent:b,section:M}).layout))}),f=[];switch(u.kind){case"module":f.push({id:"new-section",icon:"layers",label:n("devStudio.layout.newSection","New section"),onSelect:()=>p(n("devStudio.layout.newSection","New section"),"",y=>s(m,b=>$.addStudioSection(b,y).layout))});break;case"group":u.group!=="files"&&f.push(S(u.group,void 0,u.section));break;case"section":f.push({id:"rename",icon:"edit",label:n("devStudio.layout.renameSection","Rename section"),onSelect:()=>p(n("devStudio.layout.renameSection","Rename section"),l.label,y=>s(m,b=>$.renameStudioLayoutNode(b,{kind:"section",id:u.sectionId},y)))},{id:"delete",icon:"trash",danger:!0,label:n("devStudio.layout.deleteSection","Delete section"),onSelect:()=>s(m,y=>$.removeStudioLayoutNode(y,{kind:"section",id:u.sectionId}))});break;case"folder":{const y=c.folders.find(b=>b.id===u.folderId);f.push(S(u.group,u.folderId,y==null?void 0:y.section),{id:"rename",icon:"edit",label:n("devStudio.layout.renameFolder","Rename folder"),onSelect:()=>p(n("devStudio.layout.renameFolder","Rename folder"),l.label,b=>s(m,M=>$.renameStudioLayoutNode(M,{kind:"folder",id:u.folderId},b)))},{id:"delete",icon:"trash",danger:!0,label:n("devStudio.layout.deleteFolder","Delete folder"),onSelect:()=>s(m,b=>$.removeStudioLayoutNode(b,{kind:"folder",id:u.folderId}))});break}}const v=l.ref;if(v){const y=v.slice(0,v.indexOf(":")),b=c.placement[v],M=[{id:"move-new-folder",icon:"folder",label:n("devStudio.layout.moveToNewFolder","Move to a new folder…"),onSelect:()=>p(g,"",N=>s(m,k=>{const x=$.addStudioFolder(k,{label:N,group:y,section:b==null?void 0:b.section});return $.placeStudioEntry(x.layout,v,{folder:x.id})}))},...c.folders.filter(N=>N.group===y&&N.id!==(b==null?void 0:b.folder)).map(N=>({id:`move-folder-${N.id}`,icon:"folder",label:n("devStudio.layout.moveToFolder","Move to folder: {name}").replace("{name}",N.label),onSelect:()=>s(m,k=>$.placeStudioEntry(k,v,{folder:N.id}))})),...c.sections.filter(N=>N.id!==(b==null?void 0:b.section)||!!(b!=null&&b.folder)).map(N=>({id:`move-section-${N.id}`,icon:"layers",label:n("devStudio.layout.moveToSection","Move to section: {name}").replace("{name}",N.label),onSelect:()=>s(m,k=>$.placeStudioEntry(k,v,{section:N.id}))}))];(b!=null&&b.folder||b!=null&&b.section)&&M.push({id:"move-back",icon:"arrow-left",label:n("devStudio.layout.moveBack","Move back to its group"),onSelect:()=>s(m,N=>$.placeStudioEntry(N,v,{}))}),f.length&&f.push({id:"divider",divider:!0}),f.push(...M)}return f.length?f:void 0},[e.modules,i,s,n]),dialog:o?t.jsx(fn,{prompt:o,onClose:()=>a(null)}):null}}function te({icon:e,title:i,subtitle:n,badges:o,actions:a,children:s}){return t.jsxs("section",{className:"nice-development-studio__preview","data-testid":"studio-preview",children:[t.jsxs("div",{className:"nice-development-studio__preview-info",children:[t.jsxs("header",{className:"nice-development-studio__preview-head",children:[t.jsx(h.NiceIcon,{name:e,size:20}),t.jsxs("div",{className:"nice-development-studio__preview-name",children:[t.jsx("h3",{className:"nice-development-studio__preview-title",children:i}),n&&t.jsx("span",{className:"nice-development-studio__muted",children:n})]})]}),o&&t.jsx("div",{className:"nice-development-studio__preview-badges",children:o}),s]}),a&&t.jsx("footer",{className:"nice-development-studio__preview-actions",children:a})]})}function re({items:e}){const i=e.filter(([,n])=>n!=null&&n!=="");return i.length===0?null:t.jsx("dl",{className:"nice-development-studio__facts",children:i.map(([n,o])=>t.jsxs("div",{className:"nice-development-studio__fact",children:[t.jsx("dt",{children:n}),t.jsx("dd",{children:o})]},n))})}function xe({rows:e,onSelect:i,limit:n=12}){const{t:o}=h.useNiceTranslation();return e.length===0?null:t.jsxs("ul",{className:"nice-development-studio__preview-list",children:[e.slice(0,n).map(a=>t.jsxs("li",{children:[t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:t.jsx(h.NiceIcon,{name:a.icon,size:14}),onClick:()=>i(a.id),children:a.label}),a.info&&t.jsx("span",{className:"nice-development-studio__muted",children:a.info})]},a.id)),e.length>n&&t.jsx("li",{className:"nice-development-studio__muted",children:o("devStudio.preview.more","…and {count} more").replace("{count}",String(e.length-n))})]})}const Fe=e=>Array.isArray(e)?e.length:void 0;function yn(e){var c,p,g,S;const{row:i,session:n,advanced:o,onEdit:a}=e,{t:s}=h.useNiceTranslation();if(!i)return t.jsx("div",{className:"nice-development-studio__placeholder","data-testid":"studio-preview-empty",children:e.emptyText});const d=i.node,l=d.kind==="package"?Rt(d.workspaceId,n.packagesByWs[d.workspaceId],n.modulesByWs[d.workspaceId]??[]):void 0,u=Ji(d,{modules:n.modules,packages:l,advanced:o}),m=u?t.jsx(h.NiceButton,{size:"sm",variant:"primary",leftIcon:t.jsx(h.NiceIcon,{name:"edit",size:14}),onClick:()=>a(u),"data-testid":"studio-edit","data-tour":"devstudio-edit",children:d.kind==="module"?s("devStudio.preview.editSettings","Edit settings"):s("devStudio.preview.edit","Edit")}):null,r="module"in d?n.modules[Y(d.module)]:void 0;if("module"in d&&!r)return t.jsx(te,{icon:i.icon,title:i.label,children:t.jsx("p",{className:"nice-development-studio__muted",children:s("devStudio.loading","Loading…")})});switch(d.kind){case"workspace":return t.jsx(Sn,{...e,row:i,workspaceId:d.workspaceId});case"package":return t.jsx(kn,{...e,row:i,workspaceId:d.workspaceId,packageId:d.packageId,editButton:m});case"module":return t.jsx(bn,{...e,row:i,module:r,editButton:m});case"group":return t.jsx(xn,{...e,row:i,module:r,group:d.group});case"entity":return t.jsx(wn,{...e,row:i,module:r,docKey:d.docKey,index:d.index,editButton:m});case"item":return t.jsx(_n,{...e,row:i,module:r,node:d,editButton:m});case"document":return t.jsx(In,{...e,row:i,module:r,docKey:d.docKey,editButton:m});case"section":case"folder":return t.jsx(te,{icon:i.icon,title:i.label,children:t.jsx(xe,{rows:i.children??[],onSelect:e.onSelect})});case"panel":return t.jsx(te,{icon:i.icon,title:i.label,actions:m});case"file":{const f=r.working.find(v=>v.path===d.path);return t.jsx(te,{icon:"file",title:i.label,actions:m,children:t.jsx(re,{items:[[s("devStudio.preview.size","Size"),f?`${new TextEncoder().encode(f.text).length} B`:void 0],[s("devStudio.preview.state","State"),i.dirty?s("devStudio.explorer.unsaved","Unsaved changes"):void 0]]})})}case"templates":return t.jsx(te,{icon:"layers",title:i.label,actions:(c=e.provider)!=null&&c.saveTemplate&&!e.readOnly()?t.jsx(h.NiceButton,{size:"sm",variant:"primary",leftIcon:t.jsx(h.NiceIcon,{name:"plus",size:14}),onClick:e.onNewTemplate,children:s("devStudio.preview.newTemplate","New template")}):void 0,children:t.jsx(xe,{rows:i.children??[],onSelect:e.onSelect})});case"category":return t.jsx(te,{icon:"folder",title:i.label,children:t.jsx(xe,{rows:i.children??[],onSelect:e.onSelect})});case"template":{const f=(p=n.templates)==null?void 0:p.find(y=>y.id===d.templateId),v=(f==null?void 0:f.translations.en)??Object.values((f==null?void 0:f.translations)??{})[0];return t.jsxs(te,{icon:i.icon,title:i.label,subtitle:f==null?void 0:f.category,actions:m,children:[(v==null?void 0:v.description)&&t.jsx("p",{children:v.description}),t.jsx(re,{items:[["Id",f==null?void 0:f.id],[s("devStudio.preview.modules","Modules"),String((f==null?void 0:f.modules.length)??0)],[s("devStudio.preview.tags","Tags"),(g=f==null?void 0:f.tags)==null?void 0:g.join(", ")]]}),t.jsx(xe,{rows:i.children??[],onSelect:e.onSelect,limit:8})]})}case"templateModule":{const f=(S=n.templates)==null?void 0:S.find(y=>y.id===d.templateId),v=f==null?void 0:f.modules.find(y=>y.moduleId===d.moduleId);return t.jsxs(te,{icon:"box",title:i.label,subtitle:d.moduleId,actions:d.target?t.jsx(h.NiceButton,{size:"sm",variant:"primary",leftIcon:t.jsx(h.NiceIcon,{name:"arrow-right",size:14}),onClick:()=>e.onReveal({kind:"module",module:d.target}),children:s("devStudio.preview.goToModule","Go to the module")}):void 0,children:[t.jsx(re,{items:[[s("devStudio.preview.required","Required"),v!=null&&v.required?s("devStudio.preview.yes","yes"):void 0],[s("devStudio.preview.condition","Condition"),v==null?void 0:v.condition],[s("devStudio.preview.description","Description"),v==null?void 0:v.description]]}),i.missing&&t.jsx("p",{className:"nice-development-studio__error",children:s("devStudio.preview.missingModule","No project has this module.")})]})}}}function Sn({row:e,workspaceId:i,session:n,provider:o,readOnly:a,canCreateModule:s,onSelect:d,onNewModule:l,onNewPackage:u}){var p;const{t:m}=h.useNiceTranslation(),r=n.workspaces.find(g=>g.id===i),c=!a()&&!(r!=null&&r.readOnly);return t.jsxs(te,{icon:e.icon,title:e.label,badges:r!=null&&r.readOnly?t.jsx("span",{className:"nice-development-studio__tag",children:m("devStudio.explorer.readOnly","Read-only")}):void 0,actions:c&&(s||o!=null&&o.savePackage)?t.jsxs(t.Fragment,{children:[s&&t.jsx(h.NiceButton,{size:"sm",variant:"primary",leftIcon:t.jsx(h.NiceIcon,{name:"box",size:14}),onClick:()=>l({workspaceId:i}),children:m("devStudio.preview.newModule","New module")}),(o==null?void 0:o.savePackage)&&t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:t.jsx(h.NiceIcon,{name:"archive",size:14}),onClick:()=>u(i),children:m("devStudio.preview.newPackage","New package")})]}):void 0,children:[(r==null?void 0:r.description)&&t.jsx("p",{children:r.description}),t.jsx(re,{items:[[m("devStudio.preview.packages","Packages"),String(((p=e.children)==null?void 0:p.length)??0)],[m("devStudio.preview.modules","Modules"),e.info]]}),t.jsx(xe,{rows:e.children??[],onSelect:d})]})}function kn({row:e,workspaceId:i,packageId:n,session:o,readOnly:a,canCreateModule:s,editButton:d,onSelect:l,onNewModule:u}){var g;const{t:m}=h.useNiceTranslation(),r=(g=o.packagesByWs[i])==null?void 0:g.find(S=>S.id===n),c=o.workspaces.find(S=>S.id===i),p=!a()&&!(c!=null&&c.readOnly);return t.jsxs(te,{icon:e.icon,title:e.label,subtitle:n,actions:t.jsxs(t.Fragment,{children:[d,p&&s&&t.jsx(h.NiceButton,{size:"sm",variant:d?"ghost":"primary",leftIcon:t.jsx(h.NiceIcon,{name:"plus",size:14}),onClick:()=>u({workspaceId:i,packageId:n}),children:m("devStudio.preview.newModuleHere","New module here")})]}),children:[(r==null?void 0:r.description)&&t.jsx("p",{children:r.description}),t.jsx(xe,{rows:e.children??[],onSelect:l})]})}function bn(e){var z;const{row:i,module:n,session:o,preset:a,provider:s,readOnly:d,editButton:l}=e,{t:u}=h.useNiceTranslation(),m=n.key,r=(z=o.modulesByWs[m.workspaceId])==null?void 0:z.find(K=>K.id===m.id),c=d(m),p=e.issues(m),g=(r==null?void 0:r.contents)==="manifest"&&t.jsx("span",{title:u("devStudio.preview.manifestOnly","This provider gives only the manifest"),children:"—"}),S=rt(n).length,f=n.documents.filter(K=>K.kind.editor==="views").reduce((K,C)=>K+le(n,C).length,0),v=new Set(n.documents.filter(K=>K.kind.editor==="i18n").flatMap(K=>Object.keys(ie(n,K)??{}))),y={key:m,files:n.working,documents:n.documents},b=a.newFile?a.kinds.filter(K=>K.editor!=="scriptList").map(K=>{var C;return{kind:K,file:(C=a.newFile)==null?void 0:C.call(a,K.id,y)}}).filter(K=>!!K.file&&!n.working.some(C=>C.path===K.file.path)):[],[M,N]=j.useState(!1),k=!c&&Ht(n,a),x=K=>t.jsx(h.NiceIcon,{name:K,size:14}),w=[...s!=null&&s.listRevisions?[{id:"history",icon:x("clock"),label:u("devStudio.overview.history","History"),onClick:()=>e.onEdit({kind:"history",module:m})}]:[],...e.canDuplicateModule&&!d()?[{id:"duplicate",icon:x("copy"),label:u("devStudio.explorer.duplicate","Duplicate"),onClick:()=>e.onModuleAction("duplicate",m)}]:[],...s!=null&&s.saveTemplate&&o.templates&&!d()?[{id:"addToTemplate",icon:x("layers"),label:u("devStudio.explorer.addToTemplate","Add to template"),onClick:()=>e.onModuleAction("addToTemplate",m)}]:[],...k?[{id:"addScript",icon:x("code"),label:u("devStudio.scripts.add","Add script"),onClick:()=>N(!0)}]:[],...c?[]:b.map(({kind:K,file:C})=>({id:`add:${K.id}`,icon:x(K.icon??"plus"),label:`${u("devStudio.preview.add","Add:")} ${K.labelKey?u(K.labelKey,K.label):K.label}`,onClick:()=>o.setRaw(m,C.path,C.text)})),...s!=null&&s.deleteModule&&!c?[{id:"sep",divider:!0},{id:"delete",icon:x("trash"),label:u("devStudio.delete","Delete"),danger:!0,onClick:()=>e.onModuleAction("delete",m)}]:[]],_=M&&t.jsx(Yt,{module:n,preset:a,onClose:()=>N(!1),onAdd:K=>{const C=Gt(n,a,o,K);C&&e.onEdit(C)}});return t.jsxs(t.Fragment,{children:[_,t.jsxs(te,{icon:i.icon,title:i.label,subtitle:(r==null?void 0:r.location)??m.id,badges:t.jsxs(t.Fragment,{children:[(r==null?void 0:r.readOnly)&&t.jsx("span",{className:"nice-development-studio__tag",children:u("devStudio.explorer.readOnly","Read-only")}),(r==null?void 0:r.shadowedBy)&&t.jsx("span",{className:"nice-development-studio__tag",title:r.shadowedBy,children:u("devStudio.explorer.shadowed","shadowed")})]}),actions:t.jsxs(t.Fragment,{children:[l,n.dirty&&!c&&t.jsxs(t.Fragment,{children:[t.jsx(h.NiceButton,{size:"sm",variant:"primary",leftIcon:x("save"),onClick:()=>e.onSave(m),"data-tour":"devstudio-save",children:u("devStudio.saveCount","Save ({count})").replace("{count}",String(n.changes.length))}),t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:x("undo"),onClick:()=>o.discard(m),children:u("devStudio.discard","Discard changes")})]}),t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:x("check"),onClick:()=>void o.validate(m),children:u("devStudio.validate","Validate")}),t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:x(p.length===0?"success":"warning"),onClick:()=>e.onEdit({kind:"problems",module:m}),children:`${u("devStudio.overview.problems","Problems")} (${p.length})`}),w.length>0&&t.jsx(h.NiceMenu,{className:"nice-development-studio__more",variant:"ghost",size:"sm",fullWidth:!0,items:[{id:"more",icon:x("more-horizontal"),label:u("devStudio.preview.more.actions","More actions"),children:w}]})]}),children:[(r==null?void 0:r.description)&&t.jsx("p",{children:r.description}),t.jsx(re,{items:[["Id",m.id],[u("devStudio.preview.version","Version"),r==null?void 0:r.version],[u("devStudio.preview.entities","Entities"),g||String(S)],[u("devStudio.preview.views","Views"),g||String(f)],[u("devStudio.preview.languages","Languages"),g||[...v].join(", ")],[u("devStudio.preview.state","State"),n.dirty?u("devStudio.status.changed","{count} changed files").replace("{count}",String(n.changes.length)):void 0]]}),p.length>0&&t.jsxs("div",{className:"nice-development-studio__preview-issues",children:[t.jsx("ul",{className:"nice-development-studio__issues",children:p.slice(0,3).map((K,C)=>t.jsx("li",{className:`nice-development-studio__issue nice-development-studio__issue--${K.severity}`,children:t.jsxs("button",{type:"button",className:"nice-development-studio__issue-link",title:u("devStudio.problems.goTo","Go to"),onClick:()=>e.onReveal(qt(n,K)),children:[t.jsx(h.NiceIcon,{name:K.severity==="error"?"error":K.severity==="warning"?"warning":"info",size:14}),t.jsx("span",{children:Qt(u,K)})]})},C))}),p.length>3&&t.jsx("span",{className:"nice-development-studio__muted",children:u("devStudio.preview.more","…and {count} more").replace("{count}",String(p.length-3))})]})]})]})}function xn({row:e,module:i,group:n,preset:o,session:a,readOnly:s,onSelect:d,onEdit:l}){const{t:u}=h.useNiceTranslation(),[m,r]=j.useState(!1),c=s(i.key),p=n==="scripts"&&!c&&Ht(i,o),g=!c&&!p?jn(n,i,o,a):void 0;return t.jsxs(te,{icon:e.icon,title:e.label,actions:p?t.jsx(h.NiceButton,{size:"sm",variant:"primary",leftIcon:t.jsx(h.NiceIcon,{name:"plus",size:14}),onClick:()=>r(!0),"data-testid":"studio-add",children:u("devStudio.scripts.add","Add script")}):g?t.jsx(h.NiceButton,{size:"sm",variant:"primary",leftIcon:t.jsx(h.NiceIcon,{name:"plus",size:14}),onClick:()=>l(g.run()),"data-testid":"studio-add",children:g.label(u)}):void 0,children:[t.jsx(xe,{rows:e.children??[],onSelect:d}),m&&t.jsx(Yt,{module:i,preset:o,onClose:()=>r(!1),onAdd:S=>{const f=Gt(i,o,a,S);f&&l(f)}})]})}function jn(e,i,n,o){var r,c;const a=e==="entities"?"entities":e==="views"?"views":e==="workflows"?"workflows":e==="dataSources"?"dataSources":void 0,s=a?i.documents.find(p=>p.kind.editor===a&&p.model!==void 0):void 0;if(!s)return;const d=i.key;if(e==="entities"){const p=ie(i,s)??[],g=((r=n.entities)==null?void 0:r.nameKey)??"name",S=((c=n.entities)==null?void 0:c.fieldsKey)??"fields";return{label:f=>f("devStudio.preview.newEntity","New entity"),run:()=>(o.setDraft(d,s.key,[...p,{[g]:`Entity${p.length+1}`,[S]:[]}]),{kind:"entity",module:d,docKey:s.key,index:p.length})}}if(e==="dataSources"){const p=ie(i,s)??[];return{label:g=>g("devStudio.items.addDataSource","New data source"),run:()=>{const g={key:`source${p.length+1}`,kind:"query",query:{tables:[],joins:[],conditions:[],sorts:[],groupBy:[],distinct:!1},sql:""};return o.setDraft(d,s.key,[...p,g]),{kind:"item",module:d,group:"dataSources",docKey:s.key,itemKey:g.key}}}}const l=le(i,s),u=l.length+1,m=e==="views"?{id:`view-${u}`,name:`View ${u}`,version:2,columns:12,rows:[],dataSources:[]}:{id:`workflow-${u}`,name:`Workflow ${u}`,entityType:"",version:1,states:[],transitions:[]};return{label:p=>e==="views"?p("devStudio.items.addView","New view"):p("devStudio.items.addWorkflow","New workflow"),run:()=>{const p={key:m.id,label:m.name,definition:m,source:m};return o.setDraft(d,s.key,[...l,p]),{kind:"item",module:d,group:e,docKey:s.key,itemKey:m.id}}}}const Nn=[["isPrimaryKey","PK","Primary key"],["isForeignKey","FK","Foreign key"],["isRequired","Req","Required"]];function wn({row:e,module:i,docKey:n,index:o,preset:a,session:s,readOnly:d,editButton:l,onReveal:u}){var v;const{t:m}=h.useNiceTranslation(),r=me(i,n),c=r?ie(i,r):void 0,p=Array.isArray(c)?c[o]:void 0;if(!r||!c||!p)return t.jsx(te,{icon:"table",title:e.label,children:t.jsx("p",{className:"nice-development-studio__muted",children:m("devStudio.edit.gone","This is no longer in the module.")})});const g=((v=a.entities)==null?void 0:v.fieldsKey)??"fields",S=Array.isArray(p[g])?p[g]:[],f=d(i.key);return t.jsxs(te,{icon:"table",title:lt(p)||e.label,subtitle:String(p.name??""),badges:t.jsxs(t.Fragment,{children:[!!p.isAudited&&t.jsx("span",{className:"nice-development-studio__tag",children:m("entityEditor.flag.audited.abbr","Audit")}),!!p.isSoftDeleteEnabled&&t.jsx("span",{className:"nice-development-studio__tag",children:m("entityEditor.flag.softDelete.abbr","Soft-del")})]}),actions:t.jsxs(t.Fragment,{children:[l,!f&&t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:t.jsx(h.NiceIcon,{name:"trash",size:14}),onClick:()=>{s.setDraft(i.key,r.key,ct(c,o,null)),u({kind:"group",module:i.key,group:"entities"})},children:m("devStudio.delete","Delete")})]}),children:[typeof p.description=="string"&&p.description&&t.jsx("p",{children:p.description}),t.jsx(re,{items:[[m("entityEditor.col.table","Table"),p.tableName],[m("entityEditor.col.fields","Fields"),String(S.length)]]}),S.length>0&&t.jsx("table",{className:"nice-development-studio__table nice-development-studio__preview-fields",children:t.jsx("tbody",{children:S.slice(0,8).map((y,b)=>t.jsxs("tr",{children:[t.jsx("td",{children:String(y.name??"")}),t.jsx("td",{className:"nice-development-studio__muted",children:String(y.dataType??y.type??"")}),t.jsx("td",{children:Nn.filter(([M])=>y[M]||M==="isRequired"&&y.required).map(([,M,N])=>t.jsx("span",{className:"nice-development-studio__tag",title:N,children:M},M))})]},b))})}),S.length>8&&t.jsx("span",{className:"nice-development-studio__muted",children:m("devStudio.preview.more","…and {count} more").replace("{count}",String(S.length-8))})]})}function _n({row:e,module:i,node:n,advanced:o,renderViewPreview:a,editButton:s}){var g,S,f,v,y;const{t:d}=h.useNiceTranslation(),l=me(i,n.docKey),u=l?le(i,l).find(b=>b.key===n.itemKey):void 0;if(!u)return t.jsx(te,{icon:e.icon,title:e.label,children:t.jsx("p",{className:"nice-development-studio__muted",children:d("devStudio.edit.gone","This is no longer in the module.")})});const m=u.source??{},r=u.definition??{},c=n.group==="scripts"?u.definition:void 0,p=c?[[d("devStudio.scripts.name","Name"),c.name],[d("devStudio.scripts.kind","Kind"),mt(d,c.kind)],[d("devStudio.scripts.language","Language"),c.language],[d("devStudio.scripts.category","Category"),c.category],[d("devStudio.scripts.trigger","Runs on"),c.trigger],[d("devStudio.scripts.parameters","Parameters"),(g=c.parameters)==null?void 0:g.map(b=>b.name).join(", ")],[d("devStudio.scripts.returnType","Returns"),c.returnType],[d("devStudio.scripts.description","Description"),c.description]]:n.group==="views"?[["Id",u.key],[d("devStudio.preview.type","Type"),m.viewType??m.type??m.kind],[d("devStudio.preview.entity","Entity"),m.entityName??m.entity],[d("devStudio.preview.columns","Columns"),(S=Fe(m.columns))==null?void 0:S.toString()],[d("devStudio.preview.rows","Rows"),(f=Fe(r.rows))==null?void 0:f.toString()]]:n.group==="workflows"?[["Id",u.key],[d("devStudio.preview.states","States"),(v=Fe(r.states??m.states))==null?void 0:v.toString()],[d("devStudio.preview.transitions","Transitions"),(y=Fe(r.transitions??m.transitions))==null?void 0:y.toString()]]:[[d("devStudio.preview.key","Key"),u.key],[d("devStudio.preview.type","Type"),r.kind??void 0]];return t.jsxs(te,{icon:e.icon,title:u.label||u.key,badges:u.definition===void 0?t.jsx("span",{className:"nice-development-studio__tag",children:d("devStudio.tree.noForm","no designer")}):void 0,actions:s,children:[t.jsx(re,{items:p}),u.definition===void 0&&t.jsx("p",{className:"nice-development-studio__muted",children:o?d("devStudio.preview.noDesignerAdvanced","There is no designer for this kind of entry yet; edit its source."):d("devStudio.preview.noDesigner","There is no designer for this kind of entry yet.")}),n.group==="views"&&a&&t.jsx("div",{className:"nice-development-studio__preview-view",children:a({module:i.key,item:u,files:i.working})})]})}function In({row:e,module:i,docKey:n,advanced:o,editButton:a}){var m;const{t:s}=h.useNiceTranslation(),d=me(i,n);if(!d)return t.jsx(te,{icon:e.icon,title:e.label,children:t.jsx("p",{className:"nice-development-studio__muted",children:s("devStudio.edit.gone","This is no longer in the module.")})});const l=ie(i,d);let u=null;if(d.model===void 0)u=t.jsxs("p",{className:"nice-development-studio__error",role:"alert",children:[o?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.")," ",d.error]});else if(d.kind.editor==="i18n"){const r=l??{},c=Math.max(0,...Object.values(r).map(p=>Object.keys(p??{}).length));u=t.jsx(re,{items:Object.entries(r).map(([p,g])=>{const S=Object.keys(g??{}).length;return[p,S<c?s("devStudio.preview.keysMissing","{count} keys, {missing} missing").replace("{count}",String(S)).replace("{missing}",String(c-S)):s("devStudio.preview.keys","{count} keys").replace("{count}",String(S))]})})}else if(d.kind.editor==="permissions"){const r=l??{permissions:[],groups:[]};u=t.jsx(re,{items:[[s("devStudio.permissions.codes","Permissions"),String(r.permissions.length)],[s("devStudio.permissions.groups","Groups"),String(r.groups.length)]]})}else if(d.kind.editor==="seeds"){const r=l??{seeds:{}};u=t.jsx(re,{items:Object.entries(r.seeds??{}).map(([c,p])=>[c,s("devStudio.preview.rowsCount","{count} rows").replace("{count}",String(p.length))])})}else d.kind.editor==="hooks"?u=t.jsx(re,{items:[[s("devStudio.preview.bindings","Bindings"),(m=Fe(l))==null?void 0:m.toString()]]}):d.kind.editor==="script"&&(u=t.jsx(re,{items:[[s("devStudio.preview.lines","Lines"),String(String(l??"").split(`
|
|
8
|
+
`).length)]]}));return t.jsx(te,{icon:e.icon,title:e.label,subtitle:d.paths.join(", "),actions:a,children:u})}function Cn({tree:e,selected:i,expanded:n,onExpandedChange:o,onSelect:a,loadModule:s,newItems:d,actions:l,onRefresh:u,tutorialButton:m,emptyText:r,minWidth:c,contextMenuItems:p}){const{t:g}=h.useNiceTranslation(),S=j.useMemo(()=>[{field:"label",header:g("devStudio.explorer.name","Name"),render:(v,y)=>t.jsxs("span",{className:"nice-development-studio__tree-name",style:{maxWidth:`calc(100% - ${(y.depth??0)*20+28}px)`},children:[t.jsx(h.NiceIcon,{name:y.icon,size:14}),t.jsx("span",{className:`nice-development-studio__tree-label${y.missing?" nice-development-studio__missing":""}`,title:y.label,children:y.label}),y.dirty&&t.jsx("span",{className:"nice-development-studio__dot",title:g("devStudio.explorer.unsaved","Unsaved changes"),children:t.jsx(h.NiceIcon,{name:"circle",size:8})}),!!y.issues&&t.jsx("span",{className:"nice-development-studio__badge",title:g("devStudio.explorer.problems","Problems"),children:y.issues}),y.readOnly&&t.jsx("span",{title:g("devStudio.explorer.readOnly","Read-only"),children:t.jsx(h.NiceIcon,{name:"lock",size:12})}),y.noForm&&t.jsx("span",{className:"nice-development-studio__tag",children:g("devStudio.tree.noForm","no designer")}),y.shadowedBy&&t.jsx("span",{className:"nice-development-studio__tag",title:y.shadowedBy,children:g("devStudio.explorer.shadowed","shadowed")}),y.missing&&t.jsx("span",{className:"nice-development-studio__tag",children:g("devStudio.explorer.missing","missing")})]})},{field:"info",header:"",width:56,align:"right"}],[g]),f=t.jsxs("div",{className:"nice-development-studio__tree-actions",children:[d.length>0&&t.jsx(h.NiceMenu,{variant:"ghost",size:"sm",items:[{id:"new",label:g("devStudio.tree.new","New"),icon:t.jsx(h.NiceIcon,{name:"plus",size:14}),children:d}],"data-testid":"studio-new-menu"}),t.jsx(h.NiceButton,{size:"sm",variant:"ghost",ariaLabel:g("devStudio.refresh","Refresh"),onClick:u,children:t.jsx(h.NiceIcon,{name:"refresh",size:14})}),l==null?void 0:l.map(v=>t.jsx(h.NiceButton,{size:"sm",variant:"ghost",disabled:v.disabled,leftIcon:v.icon?t.jsx(h.NiceIcon,{name:v.icon,size:14}):void 0,onClick:v.onSelect,children:v.label},v.key)),m&&t.jsx("span",{className:"nice-development-studio__spacer"}),m]});return t.jsx("div",{className:"nice-development-studio__tree","data-tour":"devstudio-explorer",style:{minWidth:c},children:t.jsx(h.NiceTreeGrid,{data:e.rows,nested:!0,keyField:"id",childrenField:"children",columns:S,sortable:!1,compact:!0,searchable:!0,searchFields:["label","search"],searchPlaceholder:g("devStudio.tree.search","Search modules, entities and views"),toolbar:f,toolbarActions:["collapseAll"],expandedKeys:n,onExpandedChange:o,hasChildren:v=>v.node.kind==="module"&&!v.children,loadChildren:async v=>(v.node.kind==="module"&&await s(v.node.module),[]),onRowClick:a,contextMenuItems:p,rowClassName:v=>v.id===i?"nice-development-studio__tree-row--selected":void 0,emptyText:r,"aria-label":g("devStudio.explorer.modules","Modules"),"data-testid":"studio-tree"})})}const Tn=[{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"}],En=["en","pl","de","fr","es","uk"],$n=j.forwardRef(function(i,n){var gt,yt;const{provider:o,preset:a,defaultModule:s,defaultExplorerTab:d="modules",displayMode:l="standard",actions:u,onModuleOpen:m,onSaved:r,onError:c,reviewBeforeSave:p=!0,scriptRunner:g,scriptIo:S,renderViewPreview:f,modulePanels:v,readOnly:y=!1,height:b=720,explorerWidth:M=320,previewWidth:N=260,tutorial:k,className:x,style:w,id:_,testId:z,"data-testid":K}=i,{t:C}=h.useNiceTranslation(),V=j.useRef(null);j.useImperativeHandle(n,()=>V.current);const X=l==="advanced",A=j.useMemo(()=>typeof a=="function"?a(C):a??$.nativeStudioPreset,[a,C]),ne=j.useMemo(()=>A.locales??En,[A]),T=zi(o,A,{locales:ne,onError:c,t:C}),{openModule:L}=T,[R,H]=j.useState(""),[Q,J]=j.useState([]),[U,oe]=j.useState(null),[Ne,we]=j.useState(null),[I,F]=j.useState(null),O=j.useCallback(E=>{var P;return(P=T.modulesByWs[E.workspaceId])==null?void 0:P.find(W=>W.id===E.id)},[T.modulesByWs]),D=E=>{var P;return((P=O(E))==null?void 0:P.label)??E.id},B=j.useMemo(()=>{const E={};for(const[P,W]of Object.entries(T.modules))E[P]=[...Kt(W,A),...T.serverIssues[P]??[]];return E},[T.modules,T.serverIssues,A]),G=j.useCallback(E=>B[Y(E)]??[],[B]),Z=j.useMemo(()=>Object.fromEntries(Object.entries(B).map(([E,P])=>[E,P.filter(W=>W.severity==="error").length])),[B]),q=j.useCallback(E=>{var W;if(y)return!0;if(!E)return!1;const P=T.workspaces.find(ye=>ye.id===E.workspaceId);return!!(P!=null&&P.readOnly)||!!((W=O(E))!=null&&W.readOnly)},[y,T.workspaces,O]),ae=gn(T,q),se=j.useMemo(()=>Vi({workspaces:T.workspaces,modulesByWs:T.modulesByWs,packagesByWs:T.packagesByWs,templates:T.templates,modules:T.modules,issueCounts:Z,panels:v?E=>v({module:E.key,files:E.working,dirty:E.dirty}):void 0,advanced:X,groups:A.groups,t:C}),[A.groups,T.workspaces,T.modulesByWs,T.packagesByWs,T.templates,T.modules,Z,v,X,C]),Ce=j.useRef(!1);j.useEffect(()=>{if(!Ce.current&&T.workspaces.length>0){Ce.current=!0;const E=T.workspaces.map(P=>`w:${P.id}`);d==="templates"&&(E.push(ze),H(ze)),J(P=>[...new Set([...P,...E])])}},[T.workspaces,d]);const ee=j.useCallback(E=>{const P=wt(se,E).map(W=>W.id);J(W=>[...new Set([...W,...P])]),H(E)},[se]),pe=j.useCallback(E=>{oe(null);const P=$e(E);P&&!T.modules[Y(P)]&&L(P),we(E)},[T.modules,L]);j.useEffect(()=>{if(!Ne)return;const E=Qe(se,Ne);if(E){ee(E),we(null);return}const P=$e(Ne);if(P&&T.modules[Y(P)]){const W=Qe(se,{kind:"module",module:P});W&&ee(W),we(null)}},[Ne,se,ee,T.modules]);const he=j.useCallback(E=>{H(E.id);const P=$e(E.node);P&&!T.modules[Y(P)]&&L(P),E.node.kind==="module"&&(m==null||m(E.node.module))},[T.modules,L,m]),Le=j.useCallback(E=>{const P=se.byId.get(E);P&&(he(P),ee(E))},[se,he,ee]),pt=j.useRef(!1);j.useEffect(()=>{s&&!pt.current&&T.modulesByWs[s.workspaceId]&&(pt.current=!0,L(s).then(()=>m==null?void 0:m(s)),we({kind:"module",module:s}))},[s,T.modulesByWs,L,m]);const _e=se.byId.get(R),ce=U?"module"in U?U.module:void 0:_e?$e(_e.node):void 0,Be=j.useCallback(async E=>{const P=T.modules[Y(E)];if(!(P!=null&&P.dirty)||q(E))return;if(p){F({kind:"review",module:E});return}const W=await T.save(E);W&&!W.ok?F({kind:"review",module:E,conflict:W}):W!=null&&W.ok&&(r==null||r(E,W))},[T,q,p,r]),ht=j.useRef(()=>{});ht.current=()=>{ce&&Be(ce)},j.useEffect(()=>{const E=V.current;if(!E)return;const P=W=>{(W.ctrlKey||W.metaKey)&&!W.altKey&&W.key.toLowerCase()==="s"&&(W.preventDefault(),ht.current())};return E.addEventListener("keydown",P),()=>E.removeEventListener("keydown",P)},[]);const Xt=()=>{const E=U?_t(U):void 0;E?pe(E):oe(null)},Zt=j.useMemo(()=>{if(!U)return[];const E=_t(U),P=E?Qe(se,E):void 0,W=P?wt(se,P):[],ye=U.kind==="manifest"?C("devStudio.edit.settings","Settings"):U.kind==="problems"?C("devStudio.overview.problems","Problems"):U.kind==="history"?C("devStudio.overview.history","History"):U.kind==="template"&&!U.templateId?C("devStudio.template.new","New template"):void 0,Se=W.map(St=>({label:St.label,onClick:()=>{oe(null),ee(St.id)}}));return ye?Se.push({label:ye}):Se.length>0&&(Se[Se.length-1]={label:Se[Se.length-1].label}),Se},[U,se,ee,C]),vt=!!(o!=null&&o.createModule)&&!!A.generateModule,ei=!!(o!=null&&o.createModule)&&!!A.duplicateModule,Te=T.workspaces.filter(E=>!E.readOnly).map(E=>({id:E.id,label:E.label})),de=_e==null?void 0:_e.node,Re=de&&"workspaceId"in de?de.workspaceId:de&&"module"in de?de.module.workspaceId:void 0,ti=(de==null?void 0:de.kind)==="package"?de.packageId:de&&"module"in de?(gt=O(de.module))==null?void 0:gt.packageId:void 0,Ee=Te.some(E=>E.id===Re)?Re:(yt=Te[0])==null?void 0:yt.id,ii=y?[]:[...vt&&Ee?[{id:"module",label:C("devStudio.tree.newModule","Module…"),icon:t.jsx(h.NiceIcon,{name:"box",size:14}),onClick:()=>F({kind:"wizard",prefill:{workspaceId:Ee,packageId:Ee===Re?ti:void 0}})}]:[],...o!=null&&o.savePackage&&Ee?[{id:"package",label:C("devStudio.tree.newPackage","Package…"),icon:t.jsx(h.NiceIcon,{name:"archive",size:14}),onClick:()=>F({kind:"package",workspaceId:Ee})}]:[],...o!=null&&o.saveTemplate&&T.templates?[{id:"template",label:C("devStudio.tree.newTemplate","Template"),icon:t.jsx(h.NiceIcon,{name:"layers",size:14}),onClick:()=>oe({kind:"template",templateId:null})}]:[]],ni=(E,P)=>{F(E==="delete"?{kind:"delete",module:P}:E==="duplicate"?{kind:"duplicate",module:P}:{kind:"templates",module:P})},ft=k?t.jsx(h.NiceTutorialButton,{steps:h.resolveTutorial(k,Tn)}):void 0,Me=ce?T.modules[Y(ce)]:void 0,Ae=ce?G(ce):[],qe=T.logs[T.logs.length-1],si=t.jsxs("div",{className:"nice-development-studio__statusbar",role:"status",children:[ce&&t.jsxs(t.Fragment,{children:[t.jsx("span",{children:D(ce)}),t.jsx("span",{children:Me!=null&&Me.dirty?C("devStudio.status.changed","{count} changed files").replace("{count}",String(Me.changes.length)):C("devStudio.status.saved","Saved")}),t.jsx(h.NiceButton,{size:"sm",variant:"ghost",leftIcon:t.jsx(h.NiceIcon,{name:Ae.length===0?"check":"warning",size:12}),onClick:()=>oe({kind:"problems",module:ce}),children:Ae.length===0?C("devStudio.status.valid","No problems"):C("devStudio.status.problems","{count} problems").replace("{count}",String(Ae.length))})]}),t.jsx("span",{className:"nice-development-studio__spacer"}),T.busy?t.jsx("span",{children:C("devStudio.loading","Loading…")}):qe&&t.jsx("span",{className:`nice-development-studio__status-message nice-development-studio__status-message--${qe.level}`,children:qe.message})]}),We=(I==null?void 0:I.kind)==="review"?T.modules[Y(I.module)]:void 0,oi=`nice-development-studio${x?` ${x}`:""}`,ai=o?C("devStudio.preview.empty","Pick a module, an entity or a view in the tree."):C("devStudio.noProvider","Connect a provider to browse modules.");return t.jsxs("div",{ref:V,id:_,className:oi,style:{height:b,...w},"data-testid":K??z,children:[t.jsx(h.NiceAppShell,{className:"nice-development-studio__shell",height:"100%",rightSidebar:U?void 0:t.jsx(yn,{row:_e,tree:se,session:T,preset:A,provider:o,readOnly:q,advanced:X,issues:G,canCreateModule:vt,canDuplicateModule:ei,renderViewPreview:f,emptyText:ai,onSelect:Le,onEdit:oe,onReveal:pe,onSave:E=>void Be(E),onNewModule:E=>F({kind:"wizard",prefill:E}),onNewPackage:E=>F({kind:"package",workspaceId:E}),onNewTemplate:()=>oe({kind:"template",templateId:null}),onModuleAction:ni}),rightSidebarWidth:N,statusBar:si,bottomPanel:X?t.jsx("div",{"data-tour":"devstudio-output",className:"nice-development-studio__output",children:t.jsx(h.NiceLogConsole,{title:C("devStudio.output","Output"),entries:T.logs,onClear:T.clearLogs,maxHeight:"100%"})}):void 0,bottomPanelHeight:X?140:void 0,children:U?t.jsx(cn,{screen:U,crumbs:Zt,session:T,preset:A,provider:o,locales:ne,readOnly:q,advanced:X,issues:G,scriptRunner:g,scriptIo:S,renderViewPreview:f,modulePanels:v,tutorialButton:ft,onBack:Xt,onSave:E=>void Be(E),onReveal:pe,onScreen:oe,onNewModule:E=>F({kind:"wizard",prefill:E})}):t.jsx(Cn,{tree:se,selected:R,expanded:Q,onExpandedChange:J,onSelect:he,loadModule:async E=>{await L(E)},newItems:ii,actions:u,onRefresh:()=>void T.refresh(),tutorialButton:ft,minWidth:M,contextMenuItems:ae.menuFor,emptyText:o?C("devStudio.explorer.empty","No modules."):C("devStudio.noProvider","Connect a provider to browse modules.")})}),(I==null?void 0:I.kind)==="wizard"&&t.jsx(Ei,{open:!0,onClose:()=>F(null),session:T,preset:A,locales:ne,prefill:I.prefill,onCreated:E=>{m==null||m(E),pe({kind:"module",module:E})}}),(I==null?void 0:I.kind)==="review"&&We&&t.jsx($i,{open:!0,moduleLabel:D(I.module),changes:We.changes,original:E=>{var P;return((P=We.files.find(W=>W.path===E))==null?void 0:P.text)??""},conflict:I.conflict,onClose:()=>F(null),onSave:async()=>{const E=await T.save(I.module);E!=null&&E.ok?(F(null),r==null||r(I.module,E)):E&&F({...I,conflict:E})},onOverwrite:async()=>{const E=await T.save(I.module,{force:!0});E!=null&&E.ok&&(F(null),r==null||r(I.module,E))},onReload:async()=>{await T.reload(I.module),F(null)}}),(I==null?void 0:I.kind)==="delete"&&t.jsx(h.NiceConfirmDialog,{visible:!0,variant:"warning",header:C("devStudio.delete.title","Delete module"),message:C("devStudio.delete.message","Delete {module} and all its files?").replace("{module}",D(I.module)),acceptLabel:C("devStudio.delete","Delete"),rejectLabel:C("devStudio.cancel","Cancel"),onReject:()=>F(null),onAccept:async()=>{const E=I.module;F(null),await T.deleteModule(E)&&(oe(null),H(`w:${E.workspaceId}`))}}),ae.dialog,(I==null?void 0:I.kind)==="duplicate"&&t.jsx(jt,{open:!0,title:C("devStudio.duplicate.title","Duplicate {module}").replace("{module}",D(I.module)),workspaces:Te,workspaceId:Te.some(E=>E.id===I.module.workspaceId)?I.module.workspaceId:void 0,idLabel:C("devStudio.duplicate.id","New module id"),initialId:`${I.module.id}Copy`,onClose:()=>F(null),onSubmit:async E=>{var ye;const P=I.module;F(null);const W=await T.duplicateModule(P,{workspaceId:E.workspaceId,id:E.id,packageId:(ye=O(P))==null?void 0:ye.packageId});W&&pe({kind:"module",module:{workspaceId:W.workspaceId,id:W.id}})}}),(I==null?void 0:I.kind)==="package"&&t.jsx(jt,{open:!0,title:C("devStudio.package.new","New package"),workspaces:Te,workspaceId:I.workspaceId,idLabel:C("devStudio.package.id","Id"),withLabel:!0,onClose:()=>F(null),onSubmit:async E=>{F(null);const P=await T.savePackage({id:E.id,workspaceId:E.workspaceId,label:E.label});P&&pe({kind:"package",workspaceId:P.workspaceId,packageId:P.id})}}),(I==null?void 0:I.kind)==="templates"&&T.templates&&t.jsx(Fi,{open:!0,moduleId:I.module.id,templates:T.templates,onClose:()=>F(null),onApply:async E=>{F(null);for(const P of E)await T.saveTemplate(P,P.id)}})]})});exports.NICE_STUDIO_SCRIPT_KINDS=$.NICE_STUDIO_SCRIPT_KINDS;exports.NICE_STUDIO_SCRIPT_PHASES=$.NICE_STUDIO_SCRIPT_PHASES;exports.addStudioFolder=$.addStudioFolder;exports.addStudioSection=$.addStudioSection;exports.arrayFileKind=$.arrayFileKind;exports.buildDocuments=$.buildDocuments;exports.createMemoryStudioProvider=$.createMemoryStudioProvider;exports.defineManifestSection=$.defineManifestSection;exports.deriveDefaultRbac=$.deriveDefaultRbac;exports.detectJsonTextFormat=$.detectJsonTextFormat;exports.emptyStudioLayout=$.emptyStudioLayout;exports.encodeDocument=$.encodeDocument;exports.endsWithAny=$.endsWithAny;exports.entitiesToSchemas=$.entitiesToSchemas;exports.fileName=$.fileName;exports.fitManifestSection=$.fitManifestSection;exports.fromStudioScriptItem=$.fromStudioScriptItem;exports.i18nFileKind=$.i18nFileKind;exports.inferStudioScriptKind=$.inferStudioScriptKind;exports.isEmptyStudioLayout=$.isEmptyStudioLayout;exports.isStudioLayoutPath=$.isStudioLayoutPath;exports.itemsFileKind=$.itemsFileKind;exports.jsonFallbackKind=$.jsonFallbackKind;exports.jsonFileKind=$.jsonFileKind;exports.jsonValueFitsSchema=$.jsonValueFitsSchema;exports.jsonValuesEqual=$.jsonValuesEqual;exports.keepTextFormat=$.keepTextFormat;exports.manifestSectionKeys=$.manifestSectionKeys;exports.modulePrefix=$.modulePrefix;exports.nativeDataSourcesKind=$.nativeDataSourcesKind;exports.nativeEntitiesKind=$.nativeEntitiesKind;exports.nativeFileKinds=$.nativeFileKinds;exports.nativeHooksKind=$.nativeHooksKind;exports.nativeI18nKind=$.nativeI18nKind;exports.nativeManifestKind=$.nativeManifestKind;exports.nativeRbacKind=$.nativeRbacKind;exports.nativeScriptsKind=$.nativeScriptsKind;exports.nativeStudioPreset=$.nativeStudioPreset;exports.nativeViewsKind=$.nativeViewsKind;exports.nativeWorkflowsKind=$.nativeWorkflowsKind;exports.newStudioScript=$.newStudioScript;exports.objectFileKind=$.objectFileKind;exports.parseJsonText=$.parseJsonText;exports.parseStudioLayout=$.parseStudioLayout;exports.patchJsonText=$.patchJsonText;exports.patchJsonTextDetailed=$.patchJsonTextDetailed;exports.placeStudioEntry=$.placeStudioEntry;exports.readTranslations=$.readTranslations;exports.removeStudioLayoutNode=$.removeStudioLayoutNode;exports.renameStudioEntryRef=$.renameStudioEntryRef;exports.renameStudioLayoutNode=$.renameStudioLayoutNode;exports.resolveFileKind=$.resolveFileKind;exports.safeJson=$.safeJson;exports.scriptsFileKind=$.scriptsFileKind;exports.serializeStudioLayout=$.serializeStudioLayout;exports.slugifyModuleId=$.slugifyModuleId;exports.stringifyJsonText=$.stringifyJsonText;exports.studioEntryRef=$.studioEntryRef;exports.studioLayoutPath=$.studioLayoutPath;exports.studioScriptIdentifier=$.studioScriptIdentifier;exports.studioScriptLanguages=$.studioScriptLanguages;exports.textFallbackKind=$.textFallbackKind;exports.toStudioScriptItem=$.toStudioScriptItem;exports.writeTranslations=$.writeTranslations;exports.NiceArrayField=nt;exports.NiceDevelopmentStudio=$n;exports.NiceEntityEditor=Ft;exports.NiceEntityForm=st;exports.NiceI18nEditor=at;exports.NiceSchemaForm=Ie;exports.aiFormConfigToFormFields=mi;exports.aiFormFieldType=Tt;exports.formBuilderSchemaToNiceFormItems=ri;exports.formFieldsToFormItems=tt;exports.formSchemaToJsonSchema=fi;exports.jsonSchemaToFormItems=et;exports.schemaToFormItems=li;exports.validateAgainstJsonSchema=it;exports.validateFormSchema=ci;
|