domma-cms 0.36.3 → 0.36.4
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/admin/css/admin.css +1 -1
- package/admin/js/lib/card-builder.js +3 -3
- package/admin/js/lib/editor-folding.js +1 -1
- package/admin/js/lib/effects-builder.js +2 -2
- package/admin/js/lib/markdown-toolbar.js +3 -3
- package/admin/js/lib/shortcode-modal.js +1 -1
- package/admin/js/lib/timeline-builder.js +2 -2
- package/admin/js/views/actions-list.js +1 -1
- package/admin/js/views/api-endpoint-editor.js +3 -3
- package/admin/js/views/api-endpoints.js +2 -2
- package/admin/js/views/api-tokens.js +4 -4
- package/admin/js/views/blocks.js +5 -5
- package/admin/js/views/collection-editor.js +4 -4
- package/admin/js/views/collection-entries.js +1 -1
- package/admin/js/views/component-editor.js +1 -1
- package/admin/js/views/components.js +2 -2
- package/admin/js/views/effects.js +1 -1
- package/admin/js/views/form-editor.js +7 -7
- package/admin/js/views/layouts.js +1 -1
- package/admin/js/views/login.js +1 -1
- package/admin/js/views/menu-editor.js +8 -8
- package/admin/js/views/menu-locations.js +1 -1
- package/admin/js/views/menus.js +3 -3
- package/admin/js/views/my-profile.js +1 -1
- package/admin/js/views/notifications.js +1 -1
- package/admin/js/views/page-editor.js +29 -29
- package/admin/js/views/project-detail.js +1 -1
- package/admin/js/views/project-editor.js +1 -1
- package/admin/js/views/project-settings.js +1 -1
- package/admin/js/views/projects.js +2 -2
- package/admin/js/views/user-editor.js +1 -1
- package/admin/js/views/view-editor.js +1 -1
- package/admin/js/views/view-preview.js +1 -1
- package/admin/js/views/views-list.js +1 -1
- package/package.json +1 -1
|
@@ -6,7 +6,7 @@ function le(){I.register("bold",{viewBox:"0 0 24 24",path:"M7 5H14a3 3 0 0 1 0 6
|
|
|
6
6
|
`,i),r=o===-1?t.value.length:o+1;t.setSelectionRange(s,r),document.execCommand("copy"),t.setSelectionRange(i,i),E.toast("Line copied",{type:"info",duration:1200})}})}export function insertLine(t,e){const d=t.selectionStart,i=t.value,s=i.lastIndexOf(`
|
|
7
7
|
`,d-1)+1,o=i.indexOf(`
|
|
8
8
|
`,s);i.substring(s,o===-1?i.length:o).startsWith(e)?(replaceRange(t,s,s+e.length,""),t.setSelectionRange(Math.max(s,d-e.length),Math.max(s,d-e.length))):(replaceRange(t,s,s,e),t.setSelectionRange(d+e.length,d+e.length))}const Z=["activity","airpods","airport","alert-circle","alert-warning","ambulance","angry","annoyed","apartment","arch","archive","arrow-down","arrow-down-left","arrow-down-right","arrow-left","arrow-right","arrow-up","arrow-up-left","arrow-up-right","astonished","at-sign","attachment","award","badge","ban","bandage","bank","banknote","barbell","barcode","barn","baseball","basketball","battery","battery-charging","bauble","bell","bell-off","bells","bicycle","bitcoin","blood-drop","blush","bold","bone","book","book-closed","book-open","bookmark","bookmark-filled","bowling","box","boxing-glove","brain","bridge","briefcase","building","bus","cabin","cake","calculator","calendar","camera","camera-off","candy-cane","capsule","car","cart","cart-add","cash","cast","castle","chart-area","chart-bar","chart-bar-horizontal","chart-candlestick","chart-line","chart-pie","chat","chat-alt","check","check-circle","check-circle-filled","check-square","chevron-down","chevron-left","chevron-right","chevron-up","chevrons-down","chevrons-left","chevrons-right","chevrons-up","church","circle","circle-filled","clear-format","clipboard","clipboard-check","clipboard-list","clock","close","cloud","cloud-download","cloud-drizzle","cloud-lightning","cloud-off","cloud-rain","cloud-sun","cloud-upload","code","code-block","code-inline","cog","coins","columns","comment","compass","component","confused","cool","copy","corner-down-left","corner-down-right","corner-up-left","corner-up-right","court","cpu","credit-card","crown","crutch","cry","currency-dollar","currency-euro","currency-pound","cycling","database","dead","desktop","disappointed","dna","document","document-add","document-check","document-remove","document-text","dollar-sign","dome","dot","dots-horizontal","dots-vertical","download","droplet","droplets","dumbbell","edit","embed","emoji-happy","emoji-sad","euro-sign","exclamation","expand","expressionless","external-link","eye","eye-medical","eye-off","factory","fast-forward","feather","file-code","file-text","file-zip","fill","film","filter","fire","first-aid","fishing","flag","fog","folder","folder-add","folder-minus","folder-open","folder-plus","folder-remove","football","fortress","fuel","gamepad","garage","gauge","gift","git-branch","github","globe","golf","grid","grin","growth","hard-drive","hash","haze","heading-1","heading-2","heading-3","headphones","heart","heart-eyes","heart-filled","heart-pulse","heartbeat","help-circle","holly","home","hospital","hotel","house","image","image-add","images","inbox","indent","info","info-filled","investment","invoice","italic","joy","joystick","key","kettlebell","keyboard","laptop","laugh","layers","layout","library","lighthouse","lightning","link","link-2","link-add","linkedin","list","list-bullet","list-numbered","loader","loading","lock","log-in","log-out","lungs","mail","mail-open","map","map-pin","mask","maximize","medal","medical-cross","menu","menu-alt","message-circle","message-square","mic","mic-off","microscope","minimize","minus","minus-circle","minus-square","monitor","monument","moon","moon-star","more-horizontal","more-vertical","mosque","motorcycle","mountain","mouse","mouse-pointer","move","museum","music","nerd","neutral","notification","obelisk","office","outdent","package","palette","panel-bottom","panel-left","panel-right","panel-top","paperclip","parking","pause","pause-filled","percent","phone","phone-call","phone-incoming","phone-off","phone-outgoing","piggy-bank","pill","pill-bottle","pin","play","play-circle","play-filled","plug","plus","plus-circle","plus-square","podium","pound-sign","printer","pulse","pyramid","qrcode","question","quote","racket","radio","rage","rain","rainbow","receipt","redo","refresh","refresh-cw","reindeer","rewind","road","rotate-ccw","rotate-cw","router","rss","running","sad","safe","save","scale","scale-weight","school","search","send","server","settings","share","share-2","share-alt","shield","shield-alert","shield-check","shield-x","shipping","shocked","shopping-bag","shrink","sick","sidebar-left","sidebar-right","silly","skate","ski","skip-back","skip-forward","skyscraper","sleepy","sleigh","sliders","smartphone","smartwatch","smile","snow","snowflake","snowman","sob","soccer","sort","sparkles","speaker","spinner","square","stadium","star","star-decoration","star-eyes","star-filled","stethoscope","stop","stop-filled","stopwatch","store","strikethrough","sun","sunrise","sunset","surfboard","surprised","swimming","sync","syringe","tablet","tablet-smartphone","tag","tags","target","taxi","temple","tennis","tent","terminal","test-tube","text-center","text-left","text-right","thermometer","thermometer-medical","thermometer-sun","thinking","thumb-down","thumb-up","tongue","tool","tooth","tower","train-station","trash","tree","trending-down","trending-neutral","trending-up","trophy","truck","tv","tv-minimal","twitter","type","umbrella","underline","undo","university","unlink","unlock","upload","usb","user","user-add","user-check","user-group","user-plus","user-remove","users","vaccine","van","vault","video","video-off","volleyball","volume","volume-down","volume-mute","volume-off","volume-up","wallet","warehouse","warning","warning-filled","watch","webcam","wheelchair","whistle","wifi","wifi-off","wind","windmill","wink","wreath","x","x-circle","x-circle-filled","yoga","youtube","zany","zap"];function se(t,e,d){const i=document.querySelector(".editor-spacer-picker");if(i){i.remove();return}const s=document.createElement("div");s.className="editor-spacer-picker";const o=document.createElement("div");o.className="editor-spacer-picker-label",o.textContent="Spacer height",s.appendChild(o);const r=document.createElement("div");r.className="editor-spacer-picker-row";const l=document.createElement("input");l.type="range",l.className="editor-spacer-slider",l.min="4",l.max="200",l.step="4",l.value=d;const m=document.createElement("span");m.className="editor-spacer-slider-value",m.textContent=d+"px",l.addEventListener("input",function(){m.textContent=this.value+"px"}),r.appendChild(l),r.appendChild(m),s.appendChild(r);const p=document.createElement("button");p.type="button",p.className="btn btn-primary btn-sm editor-spacer-insert-btn",p.textContent="Insert",s.appendChild(p);function f(v){!s.contains(v.target)&&v.target!==e&&(s.remove(),document.removeEventListener("click",f,!0))}p.addEventListener("click",function(){s.remove(),document.removeEventListener("click",f,!0),insertAtCursor(t,`[spacer size="${l.value}" /]
|
|
9
|
-
`)});const n=e.getBoundingClientRect(),c=e.closest(".editor-toolbar").getBoundingClientRect();s.style.top=n.bottom-c.top+4+"px";const a=n.left-c.left;s.style.left=Math.min(a,c.width-240-8)+"px",e.closest(".editor-toolbar").appendChild(s),setTimeout(function(){document.addEventListener("click",f,!0)},0)}function ce(t,e){const d=document.querySelector(".editor-icon-picker");if(d){d.remove();return}const i=document.createElement("div");i.className="editor-icon-picker";const s=document.createElement("input");s.type="text",s.className="form-input editor-icon-picker-search",s.placeholder="Search icons\u2026",i.appendChild(s);const o=document.createElement("div");o.className="editor-icon-picker-size-row";const r=document.createElement("label");r.textContent="Size (px)";const l=document.createElement("input");l.type="number",l.className="form-input editor-icon-picker-size",l.placeholder="default",l.min="8",l.max="256",o.appendChild(r),o.appendChild(l),i.appendChild(o);const m=document.createElement("div");m.className="editor-icon-picker-grid",i.appendChild(m);function p(w){!i.contains(w.target)&&w.target!==e&&(i.remove(),document.removeEventListener("click",p,!0))}function f(w){m.textContent="";const x=w?Z.filter(S=>S.includes(w.toLowerCase())):Z;if(x.length===0){const S=document.createElement("div");S.className="editor-icon-picker-empty",S.textContent="No icons found",m.appendChild(S);return}x.forEach(function(S){const M=document.createElement("button");M.type="button",M.className="editor-icon-picker-item";const
|
|
9
|
+
`)});const n=e.getBoundingClientRect(),c=e.closest(".editor-toolbar").getBoundingClientRect();s.style.top=n.bottom-c.top+4+"px";const a=n.left-c.left;s.style.left=Math.min(a,c.width-240-8)+"px",e.closest(".editor-toolbar").appendChild(s),setTimeout(function(){document.addEventListener("click",f,!0)},0)}function ce(t,e){const d=document.querySelector(".editor-icon-picker");if(d){d.remove();return}const i=document.createElement("div");i.className="editor-icon-picker";const s=document.createElement("input");s.type="text",s.className="form-input editor-icon-picker-search",s.placeholder="Search icons\u2026",i.appendChild(s);const o=document.createElement("div");o.className="editor-icon-picker-size-row";const r=document.createElement("label");r.textContent="Size (px)";const l=document.createElement("input");l.type="number",l.className="form-input editor-icon-picker-size",l.placeholder="default",l.min="8",l.max="256",o.appendChild(r),o.appendChild(l),i.appendChild(o);const m=document.createElement("div");m.className="editor-icon-picker-grid",i.appendChild(m);function p(w){!i.contains(w.target)&&w.target!==e&&(i.remove(),document.removeEventListener("click",p,!0))}function f(w){m.textContent="";const x=w?Z.filter(S=>S.includes(w.toLowerCase())):Z;if(x.length===0){const S=document.createElement("div");S.className="editor-icon-picker-empty",S.textContent="No icons found",m.appendChild(S);return}x.forEach(function(S){const M=document.createElement("button");M.type="button",M.className="editor-icon-picker-item";const y=document.createElement("span");y.setAttribute("data-icon",S);const h=document.createElement("span");h.textContent=S,M.appendChild(y),M.appendChild(h),M.addEventListener("click",function(){i.remove(),document.removeEventListener("click",p,!0);const C=l.value.trim(),L=C?`[icon name="${S}" size="${C}" /]`:`[icon name="${S}" /]`;insertAtCursor(t,L)}),m.appendChild(M)}),Domma.icons.scan(m)}f(""),s.addEventListener("input",function(){f(this.value.trim())});const n=e.getBoundingClientRect(),c=e.closest(".editor-toolbar").getBoundingClientRect();i.style.top=n.bottom-c.top+4+"px";const a=n.left-c.left,v=320,k=c.width;i.style.left=Math.min(a,k-v-8)+"px",e.closest(".editor-toolbar").appendChild(i),requestAnimationFrame(function(){s.focus()}),setTimeout(function(){document.addEventListener("click",p,!0)},0)}function ae(t,e,d,i){const s=document.querySelector(".editor-toolbar-dropdown");if(s){s.remove();return}const o=document.createElement("div");o.className="editor-toolbar-dropdown",d.forEach(function(f){const n=document.createElement("button");if(n.type="button",n.className="editor-toolbar-dropdown-item",f.icon){const a=document.createElement("span");a.setAttribute("data-icon",f.icon),n.appendChild(a)}const c=document.createElement("span");c.textContent=f.label,n.appendChild(c),n.addEventListener("click",function(){o.remove(),document.removeEventListener("click",p,!0),J(f.action,t,e,i)}),o.appendChild(n)});const r=e.getBoundingClientRect(),l=e.closest(".editor-toolbar").getBoundingClientRect();o.style.top=r.bottom-l.top+4+"px";const m=r.left-l.left;o.style.left=Math.min(m,l.width-180-8)+"px",e.closest(".editor-toolbar").appendChild(o),Domma.icons.scan(o);function p(f){!o.contains(f.target)&&f.target!==e&&(o.remove(),document.removeEventListener("click",p,!0))}setTimeout(function(){document.addEventListener("click",p,!0)},0)}function J(t,e,d,i){const{spacerDefault:s,handlers:o}=i;if(typeof t=="function")t(e);else if(t==="block")if(o.block)o.block(e);else{const r=e.selectionStart;replaceRange(e,r,r,'[block template="" /]'),e.setSelectionRange(r+17,r+17)}else if(t==="component")o.component?o.component(e):de(e);else if(t==="button")if(o.button)o.button(e);else{const r=e.selectionStart,l=e.selectionEnd,p=`[button href="" variant="primary"]${e.value.substring(r,l)||"Click me"}[/button]`;replaceRange(e,r,l,p),e.setSelectionRange(r+14,r+14)}else if(t==="linksc")if(o.linksc)o.linksc(e);else{const r=e.selectionStart,l=e.selectionEnd,p=`[link href=""]${e.value.substring(r,l)||"Link text"}[/link]`;replaceRange(e,r,l,p),e.setSelectionRange(r+12,r+12)}else if(t==="colourpick"){const r=e.selectionStart;document.getElementById("dm-colour-overlay")?.remove();const l=document.createElement("div");l.id="dm-colour-overlay",l.style.cssText="position:fixed;inset:0;z-index:9999;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.5);";const m=document.createElement("div");m.style.cssText="background:var(--dm-surface,#1e1e2e);border:1px solid var(--dm-border,#3a3a5c);border-radius:12px;padding:1.75rem 2rem;display:flex;flex-direction:column;align-items:center;gap:1.25rem;min-width:260px;box-shadow:var(--dm-shadow-lg);";const p=document.createElement("p");p.textContent="Colour Picker",p.style.cssText="margin:0;font-weight:700;font-size:1rem;letter-spacing:.02em;";const f=document.createElement("input");f.type="color",f.value="#000000",f.style.cssText="width:160px;height:110px;cursor:pointer;border:none;background:none;padding:0;border-radius:6px;overflow:hidden;";const n=document.createElement("div");n.style.cssText="display:flex;align-items:center;gap:.5rem;";const c=document.createElement("input");c.type="text",c.value="#000000",c.className="form-input",c.style.cssText="font-family:monospace;width:100px;text-transform:uppercase;letter-spacing:.05em;";const a=document.createElement("button");a.type="button",a.className="btn btn-ghost btn-sm",a.textContent="Copy";const v=document.createElement("button");v.type="button",v.className="btn btn-primary btn-sm",v.textContent="Insert";const k=()=>l.remove();f.addEventListener("input",()=>{c.value=f.value}),c.addEventListener("input",()=>{/^#[0-9a-f]{6}$/i.test(c.value)&&(f.value=c.value)}),a.addEventListener("click",()=>{const w=document.createElement("input");w.value=c.value,document.body.appendChild(w),w.select(),document.execCommand("copy"),w.remove(),a.textContent="Copied!",setTimeout(()=>{a.textContent="Copy"},1500)}),v.addEventListener("click",()=>{e.selectionStart=e.selectionEnd=r,insertAtCursor(e,c.value),k()}),l.addEventListener("click",w=>{w.target===l&&k()}),n.appendChild(c),n.appendChild(a),n.appendChild(v),m.appendChild(p),m.appendChild(f),m.appendChild(n),l.appendChild(m),document.body.appendChild(l)}else if(t==="link")o.link&&o.link(e);else if(t==="image")o.image&&o.image(e);else if(t==="card")if(o.card)o.card(e);else{const r=e.selectionStart,l=e.selectionEnd,p=`[card title="Card Title"]
|
|
10
10
|
${e.value.substring(r,l)||"Content here"}
|
|
11
11
|
[/card]`;replaceRange(e,r,l,p),e.setSelectionRange(r+13,r+23)}else if(t==="hero")if(o.hero)o.hero(e);else{const r=e.selectionStart,l=e.selectionEnd,p=`[hero title="Hero Title" tagline="A short tagline" size="lg"]
|
|
12
12
|
${e.value.substring(r,l)||"Optional body content here."}
|
|
@@ -41,6 +41,6 @@ Describe this event.
|
|
|
41
41
|
[item title="Item 1"]Content here.[/item]
|
|
42
42
|
[item title="Item 2"]Content here.[/item]
|
|
43
43
|
[/accordion]
|
|
44
|
-
`)}else if(t==="text"){let n=function(b,u){const g=document.createElement("div"),z=document.createElement("label");return z.style.cssText=p,z.textContent=b,g.appendChild(z),g.appendChild(u),g},c=function(b){const u=document.createElement("select");return u.style.cssText=f,[["","\u2014 default \u2014"],...b].forEach(([g,z])=>{const O=document.createElement("option");O.value=g,O.textContent=z,u.appendChild(O)}),u},a=function(b,u){const g=document.createElement("input");return g.type="text",g.placeholder=b||"",g.value=u||"",g.style.cssText=f,g},v=function(b){const u=document.createElement("label");u.style.cssText="display:flex;align-items:center;gap:.5rem;cursor:pointer;";const g=document.createElement("input");g.type="checkbox";const z=document.createElement("span");return z.style.cssText="font-size:.85em;color:var(--dm-text,#eee);",z.textContent=b,u.appendChild(g),u.appendChild(z),{wrap:u,cb:g}},
|
|
44
|
+
`)}else if(t==="text"){let n=function(b,u){const g=document.createElement("div"),z=document.createElement("label");return z.style.cssText=p,z.textContent=b,g.appendChild(z),g.appendChild(u),g},c=function(b){const u=document.createElement("select");return u.style.cssText=f,[["","\u2014 default \u2014"],...b].forEach(([g,z])=>{const O=document.createElement("option");O.value=g,O.textContent=z,u.appendChild(O)}),u},a=function(b,u){const g=document.createElement("input");return g.type="text",g.placeholder=b||"",g.value=u||"",g.style.cssText=f,g},v=function(b){const u=document.createElement("label");u.style.cssText="display:flex;align-items:center;gap:.5rem;cursor:pointer;";const g=document.createElement("input");g.type="checkbox";const z=document.createElement("span");return z.style.cssText="font-size:.85em;color:var(--dm-text,#eee);",z.textContent=b,u.appendChild(g),u.appendChild(z),{wrap:u,cb:g}},k=function(b,u){const g=document.createElement("div");return g.style.cssText="display:grid;grid-template-columns:1fr 1fr;gap:.5rem;",g.appendChild(b),g.appendChild(u),g},w=function(b){const u=document.createElement("div");return u.style.cssText="border-top:1px solid var(--dm-border,#333);padding-top:.5rem;margin-top:.1rem;font-size:.65rem;font-weight:700;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.08em;",u.textContent=b,u},_=function(){const b=[];M.value&&b.push(`font-size:${ee[M.value]||M.value}`);const u=parseFloat(y.value);!isNaN(u)&&u>0&&b.push(`font-size:${u}pt`),L.checked?b.push("font-weight:700"):h.value&&b.push(`font-weight:${te[h.value]||h.value}`),T.checked&&b.push("font-style:italic");const g=B.value.trim();g&&b.push(`color:${Y[g]||g}`),j.value&&b.push(`font-family:${oe[j.value]}`),A.value&&b.push(`text-transform:${ie[A.value]}`),W.value&&b.push(`text-decoration:${re[W.value]}`),P.value&&b.push(`letter-spacing:${ne[P.value]}`),H.value&&(b.push("display:block"),b.push(`text-align:${H.value}`)),D.value.trim()&&b.push(D.value.trim()),q.style.cssText=b.join(";"),q.textContent=S.value||"Preview text"};const r=e.selectionStart,l=e.selectionEnd,m=e.value.substring(r,l)||"",p="display:block;font-size:.7rem;font-weight:600;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",f="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;",x=document.createElement("div");x.style.cssText="padding:1rem;display:flex;flex-direction:column;gap:.6rem;overflow-y:auto;max-height:75vh;";const S=a("Text to style\u2026",m);x.appendChild(n("Content",S)),x.appendChild(w("Typography"));const M=c([["xs","xs \u2014 0.75rem"],["sm","sm \u2014 0.875rem"],["base","base \u2014 1rem"],["lg","lg \u2014 1.125rem"],["xl","xl \u2014 1.25rem"],["2xl","2xl \u2014 1.5rem"],["3xl","3xl \u2014 1.875rem"],["4xl","4xl \u2014 2.25rem"]]),y=a("pt value (overrides Size)");x.appendChild(k(n("Size",M),n("Point Size (pt)",y)));const h=c([["thin","Thin (100)"],["light","Light (300)"],["normal","Normal (400)"],["medium","Medium (500)"],["semibold","Semibold (600)"],["bold","Bold (700)"],["extrabold","Extrabold (800)"],["black","Black (900)"]]),{wrap:C,cb:L}=v("Bold (overrides Weight)"),{wrap:N,cb:T}=v("Italic"),R=document.createElement("div");R.style.cssText="display:flex;flex-direction:column;gap:.4rem;justify-content:flex-end;",R.appendChild(C),R.appendChild(N),x.appendChild(k(n("Weight",h),R)),x.appendChild(w("Appearance"));const B=a("e.g. primary, #ff0000"),j=c([["Georgia","Georgia (serif)"],["Arial","Arial (sans-serif)"],["Verdana","Verdana (sans-serif)"],["Courier New","Courier New (mono)"],["Times New Roman","Times New Roman (serif)"],["Trebuchet MS","Trebuchet MS"]]);x.appendChild(k(n("Colour",B),n("Font",j))),x.appendChild(w("Formatting"));const A=c([["upper","Uppercase"],["lower","Lowercase"],["capitalize","Capitalise"],["none","None"]]),W=c([["underline","Underline"],["line-through","Line-through"],["none","None"]]);x.appendChild(k(n("Transform",A),n("Decoration",W)));const P=c([["tight","Tight"],["normal","Normal"],["wide","Wide"],["wider","Wider"]]),H=c([["left","Left"],["center","Centre"],["right","Right"],["justify","Justify"]]);x.appendChild(k(n("Spacing",P),n("Align",H))),x.appendChild(w("Advanced"));const D=a("e.g. margin-top:1rem;display:block");x.appendChild(n("Style",D));const F=a("CSS class(es)"),G=a("ID");x.appendChild(k(n("Class",F),n("ID",G)));const K=document.createElement("div");K.style.cssText="padding:.75rem;background:var(--dm-background-alt,#111);border-radius:4px;min-height:2.5rem;display:flex;align-items:center;";const q=document.createElement("span");q.textContent=m||"Preview text",K.appendChild(q),x.appendChild(n("Preview",K));const Y={primary:"var(--dm-primary)",secondary:"var(--dm-secondary)",muted:"var(--dm-text-muted)",danger:"var(--dm-danger)",success:"var(--dm-success)",warning:"var(--dm-warning)",info:"var(--dm-info)"},ee={xs:".75rem",sm:".875rem",base:"1rem",lg:"1.125rem",xl:"1.25rem","2xl":"1.5rem","3xl":"1.875rem","4xl":"2.25rem"},te={thin:"100",light:"300",normal:"400",medium:"500",semibold:"600",bold:"700",extrabold:"800",black:"900"},ne={tight:"-0.05em",normal:"0em",wide:"0.05em",wider:"0.1em"},oe={Georgia:"Georgia,serif",Arial:"Arial,sans-serif",Verdana:"Verdana,sans-serif","Courier New":"'Courier New',monospace","Times New Roman":"'Times New Roman',serif","Trebuchet MS":"'Trebuchet MS',sans-serif"},ie={upper:"uppercase",lower:"lowercase",capitalize:"capitalize",none:"none"},re={underline:"underline","line-through":"line-through",none:"none"};L.addEventListener("change",()=>{h.disabled=L.checked,L.checked&&(h.value=""),_()}),[M,h,j,A,W,P,H].forEach(b=>{b.addEventListener("change",_)}),[B,S,D,y].forEach(b=>{b.addEventListener("input",_)}),T.addEventListener("change",_);const V=document.createElement("button");V.type="button",V.className="btn btn-primary",V.textContent="Insert",x.appendChild(V);const U=E.slideover({title:"Style Text",size:"md",position:"right",content:x});U.open(),V.addEventListener("click",()=>{const b=S.value;if(!b.trim())return;const u=[];M.value&&u.push(`size="${M.value}"`);const g=parseFloat(y.value);!isNaN(g)&&g>0&&u.push(`point-size="${g}"`),L.checked?u.push("bold"):h.value&&u.push(`weight="${h.value}"`),T.checked&&u.push("italic"),B.value.trim()&&u.push(`color="${B.value.trim()}"`),j.value&&u.push(`font="${j.value}"`),A.value&&u.push(`transform="${A.value}"`),W.value&&u.push(`decoration="${W.value}"`),P.value&&u.push(`spacing="${P.value}"`),H.value&&u.push(`align="${H.value}"`),D.value.trim()&&u.push(`style="${D.value.trim().replace(/"/g,""")}"`),F.value.trim()&&u.push(`class="${F.value.trim()}"`),G.value.trim()&&u.push(`id="${G.value.trim()}"`);const O=`[text${u.length?" "+u.join(" "):""}]${b}[/text]`;U.close(),insertAtCursor(e,O)})}else t==="help"?o.help&&o.help(e):t==="tutorial"&&o.tutorial&&o.tutorial(e)}const Q=[{icon:"bold",title:"Bold (Ctrl+B)",action:t=>wrapSelection(t,"**","**")},{icon:"italic",title:"Italic (Ctrl+I)",action:t=>wrapSelection(t,"_","_")},{icon:"strikethrough",title:"Strikethrough",action:t=>wrapSelection(t,"~~","~~")},"|",{type:"dropdown",icon:"heading-1",title:"Headings",items:[{label:"Heading 1",icon:"heading-1",action:t=>insertLine(t,"# ")},{label:"Heading 2",icon:"heading-2",action:t=>insertLine(t,"## ")},{label:"Heading 3",icon:"heading-3",action:t=>insertLine(t,"### ")}]},"|",{icon:"list-bullet",title:"Bullet list",action:t=>insertLine(t,"- ")},{icon:"list-numbered",title:"Numbered list",action:t=>insertLine(t,"1. ")},"|",{type:"dropdown",icon:"quote",title:"Paragraph",items:[{label:"Blockquote",icon:"quote",action:t=>insertLine(t,"> ")},{label:"Horizontal rule",icon:"minus-circle",action:t=>insertAtCursor(t,`
|
|
45
45
|
---
|
|
46
|
-
`)}]},"|",{type:"dropdown",icon:"code-inline",title:"Code",items:[{label:"Inline code",icon:"code-inline",action:t=>wrapSelection(t,"`","`")},{label:"Code block",icon:"code-block",action:t=>wrapSelection(t,"\n```\n","\n```\n")}]},"|",{type:"dropdown",icon:"plus-circle",title:"Insert",items:[{label:"Accordion",icon:"accordion-insert",action:"accordion"},{label:"Banner",icon:"banner-insert",action:"banner"},{label:"Badge",icon:"badge",action:"badge"},{label:"Block",icon:"layout",action:"block"},{label:"Button",icon:"btn-insert",action:"button"},{label:"Card",icon:"card",action:"card"},{label:"Carousel",icon:"carousel-insert",action:"carousel"},{label:"Colour Picker",icon:"colour-picker",action:"colourpick"},{label:"Collection",icon:"database",action:"collection"},{label:"Component",icon:"component",action:"component"},{label:"CTA Button",icon:"mouse-pointer",action:"cta"},{label:"Embed",icon:"video",action:"embed"},{label:"Form",icon:"file-text",action:"form"},{label:"Grid",icon:"columns",action:"grid"},{label:"Hero",icon:"hero",action:"hero"},{label:"Icon",icon:"icon-pick",action:"iconpick"},{label:"Image",icon:"image-add",action:"image"},{label:"Link",icon:"link-shortcode",action:"linksc"},{label:"List Group",icon:"list",action:"listgroup"},{label:"Scribe",icon:"scribe-insert",action:"scribe"},{label:"Spacer",icon:"spacer-insert",action:"spacerpick"},{label:"Tabs",icon:"layout-list",action:"tabs"},{label:"Text",icon:"text-style",action:"text"},{label:"Timeline",icon:"activity",action:"timeline"},{label:"View",icon:"eye",action:"view"}]},"|",{icon:"sparkles",title:"Effects",action:"effects"},{icon:"book-open",title:"CRUD tutorial",action:"tutorial"},{icon:"help-circle",title:"Editor help",action:"help"}];export function createToolbar(t,e,d={}){le();const i={link:null,image:null,card:null,grid:null,help:null,tutorial:null,effects:null,collection:null,view:null,cta:null,form:null,button:null,linksc:null,tabs:null,accordion:null,carousel:null,hero:null,banner:null},s=d.spacerDefault??40,o=t.get(0),r=e.get(0);r.textContent="",Q.forEach((n,c)=>{if(n==="|"){const a=document.createElement("span");a.className="editor-toolbar-sep",r.appendChild(a)}else{const a=document.createElement("button");a.className=n.type==="dropdown"?"editor-toolbar-btn editor-toolbar-dropdown-trigger":"editor-toolbar-btn",a.setAttribute("data-tooltip",n.title),a.setAttribute("data-idx",String(c)),a.type="button";const v=document.createElement("span");if(v.setAttribute("data-icon",n.icon),a.appendChild(v),n.type==="dropdown"){const y=document.createElement("span");y.className="editor-toolbar-caret",y.textContent="\u25BE",a.appendChild(y)}r.appendChild(a)}});const l=document.createElement("div");l.className="editor-toolbar-right",[{mode:"split",icon:"columns",label:"Split view",active:!0},{mode:"write",icon:"file-text",label:"Write only",active:!1},{mode:"preview",icon:"eye",label:"Preview only",active:!1}].forEach(n=>{const c=document.createElement("button");c.className="editor-view-btn"+(n.active?" active":""),c.setAttribute("data-mode",n.mode),c.setAttribute("data-tooltip",n.label),c.type="button";const a=document.createElement("span");a.setAttribute("data-icon",n.icon),c.appendChild(a),l.appendChild(c)});const m=document.createElement("span");m.className="editor-toolbar-sep",l.appendChild(m);const p=document.createElement("button");p.id="fullscreen-btn",p.className="editor-toolbar-btn",p.setAttribute("data-tooltip","Toggle fullscreen"),p.type="button";const f=document.createElement("span");return f.setAttribute("data-icon","expand"),p.appendChild(f),l.appendChild(p),r.appendChild(l),Domma.icons.scan(),r.querySelectorAll("[data-tooltip]").forEach(n=>{E.tooltip(n,{content:n.getAttribute("data-tooltip"),position:"top"})}),e.on("click",".editor-toolbar-btn[data-idx]",function(){const n=parseInt($(this).data("idx"),10),c=Q[n];if(!c||c==="|")return;const a=e.get(0).querySelector(`[data-idx="${n}"]`),v={spacerDefault:s,handlers:i};c.type==="dropdown"?ae(o,a,c.items,v):J(c.action,o,a,v)}),attachEditorKeybindings(o),o.addEventListener("keydown",n=>{const c=n.key.toLowerCase();(n.ctrlKey||n.metaKey)&&(c==="b"?(n.preventDefault(),wrapSelection(o,"**","**")):c==="i"?(n.preventDefault(),wrapSelection(o,"_","_")):c==="k"&&(n.preventDefault(),i.link&&i.link(o)))}),{$toolbar:e,onLink(n){i.link=n},onImage(n){i.image=n},onCard(n){i.card=n},onGrid(n){i.grid=n},onHelp(n){i.help=n},onTutorial(n){i.tutorial=n},onEffects(n){i.effects=n},onCollection(n){i.collection=n},onBlock(n){i.block=n},onView(n){i.view=n},onCta(n){i.cta=n},onForm(n){i.form=n},onButton(n){i.button=n},onLinkShortcode(n){i.linksc=n},onTabs(n){i.tabs=n},onCarousel(n){i.carousel=n},onAccordion(n){i.accordion=n},onHero(n){i.hero=n},onBanner(n){i.banner=n},onListGroup(n){i.listgroup=n},onScribe(n){i.scribe=n},onTimeline(n){i.timeline=n}}}async function de(t){const{api:e}=await import("../api.js");let d;try{d=await e.components.list()}catch(k){E.toast(k.message||"Failed to load components.",{type:"error"});return}if(!d?.length){E.toast("No components yet. Create one in Data \u2192 Components first.",{type:"info"});return}const i=E.slideover({title:"Insert Component",size:"lg",position:"right"}),s=document.createElement("div");s.style.cssText="display:flex;flex-direction:column;gap:1rem;padding:.75rem;min-height:100%;";const o=document.createElement("div");o.style.cssText="font-size:.72rem;letter-spacing:.05em;text-transform:uppercase;color:var(--dm-text-muted,#888);",o.textContent="Gallery";const r=document.createElement("div");r.style.cssText="display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:.5rem;";const l=document.createElement("div");l.style.cssText="font-size:.72rem;letter-spacing:.05em;text-transform:uppercase;color:var(--dm-text-muted,#888);",l.textContent="Props";const m=document.createElement("div");m.style.cssText="padding:.6rem;border:1px solid var(--dm-border,rgba(255,255,255,.08));border-radius:4px;min-height:40px;",m.textContent="Select a component from the gallery above.";const p=document.createElement("div");p.style.cssText="font-size:.72rem;letter-spacing:.05em;text-transform:uppercase;color:var(--dm-text-muted,#888);",p.textContent="Preview";const f=document.createElement("iframe");f.src="/admin/preview/component-preview.html",f.style.cssText="width:100%;min-height:180px;border:1px solid var(--dm-border,rgba(255,255,255,.08));border-radius:4px;background:#fff;";const n=document.createElement("div");n.style.cssText="display:flex;justify-content:flex-end;gap:.5rem;margin-top:auto;padding-top:.75rem;border-top:1px solid var(--dm-border,rgba(255,255,255,.08));";const c=document.createElement("button");c.className="btn btn-ghost",c.textContent="Cancel";const a=document.createElement("button");a.className="btn btn-primary",a.textContent="Insert",a.disabled=!0,n.appendChild(c),n.appendChild(a),s.appendChild(o),s.appendChild(r),s.appendChild(l),s.appendChild(m),s.appendChild(p),s.appendChild(f),s.appendChild(n),i.setContent(s),i.open();let v=null,y={};function w(){r.replaceChildren();for(const k of d){const h=document.createElement("button");h.type="button",h.className="btn btn-ghost",h.style.cssText="display:flex;flex-direction:column;align-items:flex-start;gap:.25rem;padding:.6rem;border:1px solid var(--dm-border,rgba(255,255,255,.08));border-radius:4px;text-align:left;";const C=document.createElement("strong");C.style.cssText="font-size:.9rem;",C.textContent=k.name;const L=document.createElement("span");L.style.cssText="font-size:.72rem;color:var(--dm-text-muted,#888);",L.textContent=`${Object.keys(k.props||{}).length} prop(s)`,h.appendChild(C),h.appendChild(L),h.addEventListener("click",()=>x(k)),r.appendChild(h)}}function x(k){v=k,y={};for(const[h,C]of Object.entries(k.props||{}))y[h]=C.default!==void 0?C.default:"";a.disabled=!1,S(),M()}function S(){m.replaceChildren();const k=Object.entries(v.props||{});if(k.length===0){const h=document.createElement("p");h.className="text-muted",h.style.margin="0",h.textContent="This component takes no props.",m.appendChild(h);return}for(const[h,C]of k){const L=document.createElement("div");L.style.cssText="display:flex;align-items:center;gap:.5rem;margin-bottom:.4rem;";const N=document.createElement("label");N.style.cssText="font-size:.8rem;min-width:120px;color:var(--dm-text-muted,#aaa);",N.textContent=C.label||h,L.appendChild(N);const T=pe(C);ue(T,C,y[h]),T.addEventListener("input",()=>{y[h]=X(T,C),f.contentWindow?.postMessage({type:"update",payload:{props:y}},"*")}),T.addEventListener("change",()=>{y[h]=X(T,C),f.contentWindow?.postMessage({type:"update",payload:{props:y}},"*")}),L.appendChild(T),m.appendChild(L)}}async function M(){if(v)try{const k=await fetch(`/api/components/${encodeURIComponent(v.name)}.js`);if(!k.ok)throw new Error(`Failed to load component (${k.status})`);const h=await k.text();f.contentWindow?.postMessage({type:"remount",payload:{compiledJs:h,tagName:`dm-${v.name}`,props:y}},"*")}catch(k){E.toast(k.message||"Failed to load preview.",{type:"error"})}}c.addEventListener("click",()=>i.close()),a.addEventListener("click",()=>{if(!v)return;const k=t.selectionStart,h=t.selectionEnd,C=Object.entries(y).map(([N,T])=>{const R=N.replace(/([A-Z])/g,"-$1").toLowerCase(),B=String(T??"").replace(/"/g,""");return`${R}="${B}"`}).join(" "),L=`[component name="${v.name}"${C?" "+C:""} /]`;replaceRange(t,k,h,L),i.close()}),w()}function pe(t){let e;return t.type==="number"?(e=document.createElement("input"),e.type="number",e.className="form-input form-input--sm"):t.type==="boolean"?(e=document.createElement("input"),e.type="checkbox",e.className="form-check"):t.type==="array"||t.type==="object"?(e=document.createElement("textarea"),e.rows=2,e.className="form-input form-input--sm",e.style.fontFamily="var(--dm-font-mono, monospace)"):(e=document.createElement("input"),e.type="text",e.className="form-input form-input--sm"),e.style.flex="1",e}function X(t,e){if(e.type==="number")return t.value===""?null:Number(t.value);if(e.type==="boolean")return!!t.checked;if(e.type==="array"||e.type==="object")try{return JSON.parse(t.value||"null")}catch{return null}return t.value}function ue(t,e,d){e.type==="boolean"?t.checked=!!d:e.type==="array"||e.type==="object"?t.value=JSON.stringify(d??null):t.value=d??""}
|
|
46
|
+
`)}]},"|",{type:"dropdown",icon:"code-inline",title:"Code",items:[{label:"Inline code",icon:"code-inline",action:t=>wrapSelection(t,"`","`")},{label:"Code block",icon:"code-block",action:t=>wrapSelection(t,"\n```\n","\n```\n")}]},"|",{type:"dropdown",icon:"plus-circle",title:"Insert",items:[{label:"Accordion",icon:"accordion-insert",action:"accordion"},{label:"Banner",icon:"banner-insert",action:"banner"},{label:"Badge",icon:"badge",action:"badge"},{label:"Block",icon:"layout",action:"block"},{label:"Button",icon:"btn-insert",action:"button"},{label:"Card",icon:"card",action:"card"},{label:"Carousel",icon:"carousel-insert",action:"carousel"},{label:"Colour Picker",icon:"colour-picker",action:"colourpick"},{label:"Collection",icon:"database",action:"collection"},{label:"Component",icon:"component",action:"component"},{label:"CTA Button",icon:"mouse-pointer",action:"cta"},{label:"Embed",icon:"video",action:"embed"},{label:"Form",icon:"file-text",action:"form"},{label:"Grid",icon:"columns",action:"grid"},{label:"Hero",icon:"hero",action:"hero"},{label:"Icon",icon:"icon-pick",action:"iconpick"},{label:"Image",icon:"image-add",action:"image"},{label:"Link",icon:"link-shortcode",action:"linksc"},{label:"List Group",icon:"list",action:"listgroup"},{label:"Scribe",icon:"scribe-insert",action:"scribe"},{label:"Spacer",icon:"spacer-insert",action:"spacerpick"},{label:"Tabs",icon:"layout-list",action:"tabs"},{label:"Text",icon:"text-style",action:"text"},{label:"Timeline",icon:"activity",action:"timeline"},{label:"View",icon:"eye",action:"view"}]},"|",{icon:"sparkles",title:"Effects",action:"effects"},{icon:"book-open",title:"CRUD tutorial",action:"tutorial"},{icon:"help-circle",title:"Editor help",action:"help"}];export function createToolbar(t,e,d={}){le();const i={link:null,image:null,card:null,grid:null,help:null,tutorial:null,effects:null,collection:null,view:null,cta:null,form:null,button:null,linksc:null,tabs:null,accordion:null,carousel:null,hero:null,banner:null},s=d.spacerDefault??40,o=t.get(0),r=e.get(0);r.textContent="",Q.forEach((n,c)=>{if(n==="|"){const a=document.createElement("span");a.className="editor-toolbar-sep",r.appendChild(a)}else{const a=document.createElement("button");a.className=n.type==="dropdown"?"editor-toolbar-btn editor-toolbar-dropdown-trigger":"editor-toolbar-btn",a.setAttribute("data-tooltip",n.title),a.setAttribute("data-idx",String(c)),a.type="button";const v=document.createElement("span");if(v.setAttribute("data-icon",n.icon),a.appendChild(v),n.type==="dropdown"){const k=document.createElement("span");k.className="editor-toolbar-caret",k.setAttribute("data-icon","chevron-down"),k.setAttribute("data-icon-size","12"),k.style.cssText="display:inline-flex;align-items:center;vertical-align:middle;",a.appendChild(k)}r.appendChild(a)}});const l=document.createElement("div");l.className="editor-toolbar-right",[{mode:"split",icon:"columns",label:"Split view",active:!0},{mode:"write",icon:"file-text",label:"Write only",active:!1},{mode:"preview",icon:"eye",label:"Preview only",active:!1}].forEach(n=>{const c=document.createElement("button");c.className="editor-view-btn"+(n.active?" active":""),c.setAttribute("data-mode",n.mode),c.setAttribute("data-tooltip",n.label),c.type="button";const a=document.createElement("span");a.setAttribute("data-icon",n.icon),c.appendChild(a),l.appendChild(c)});const m=document.createElement("span");m.className="editor-toolbar-sep",l.appendChild(m);const p=document.createElement("button");p.id="fullscreen-btn",p.className="editor-toolbar-btn",p.setAttribute("data-tooltip","Toggle fullscreen"),p.type="button";const f=document.createElement("span");return f.setAttribute("data-icon","expand"),p.appendChild(f),l.appendChild(p),r.appendChild(l),Domma.icons.scan(),r.querySelectorAll("[data-tooltip]").forEach(n=>{E.tooltip(n,{content:n.getAttribute("data-tooltip"),position:"top"})}),e.on("click",".editor-toolbar-btn[data-idx]",function(){const n=parseInt($(this).data("idx"),10),c=Q[n];if(!c||c==="|")return;const a=e.get(0).querySelector(`[data-idx="${n}"]`),v={spacerDefault:s,handlers:i};c.type==="dropdown"?ae(o,a,c.items,v):J(c.action,o,a,v)}),attachEditorKeybindings(o),o.addEventListener("keydown",n=>{const c=n.key.toLowerCase();(n.ctrlKey||n.metaKey)&&(c==="b"?(n.preventDefault(),wrapSelection(o,"**","**")):c==="i"?(n.preventDefault(),wrapSelection(o,"_","_")):c==="k"&&(n.preventDefault(),i.link&&i.link(o)))}),{$toolbar:e,onLink(n){i.link=n},onImage(n){i.image=n},onCard(n){i.card=n},onGrid(n){i.grid=n},onHelp(n){i.help=n},onTutorial(n){i.tutorial=n},onEffects(n){i.effects=n},onCollection(n){i.collection=n},onBlock(n){i.block=n},onView(n){i.view=n},onCta(n){i.cta=n},onForm(n){i.form=n},onButton(n){i.button=n},onLinkShortcode(n){i.linksc=n},onTabs(n){i.tabs=n},onCarousel(n){i.carousel=n},onAccordion(n){i.accordion=n},onHero(n){i.hero=n},onBanner(n){i.banner=n},onListGroup(n){i.listgroup=n},onScribe(n){i.scribe=n},onTimeline(n){i.timeline=n}}}async function de(t){const{api:e}=await import("../api.js");let d;try{d=await e.components.list()}catch(y){E.toast(y.message||"Failed to load components.",{type:"error"});return}if(!d?.length){E.toast("No components yet. Create one in Data \u2192 Components first.",{type:"info"});return}const i=E.slideover({title:"Insert Component",size:"lg",position:"right"}),s=document.createElement("div");s.style.cssText="display:flex;flex-direction:column;gap:1rem;padding:.75rem;min-height:100%;";const o=document.createElement("div");o.style.cssText="font-size:.72rem;letter-spacing:.05em;text-transform:uppercase;color:var(--dm-text-muted,#888);",o.textContent="Gallery";const r=document.createElement("div");r.style.cssText="display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:.5rem;";const l=document.createElement("div");l.style.cssText="font-size:.72rem;letter-spacing:.05em;text-transform:uppercase;color:var(--dm-text-muted,#888);",l.textContent="Props";const m=document.createElement("div");m.style.cssText="padding:.6rem;border:1px solid var(--dm-border,rgba(255,255,255,.08));border-radius:4px;min-height:40px;",m.textContent="Select a component from the gallery above.";const p=document.createElement("div");p.style.cssText="font-size:.72rem;letter-spacing:.05em;text-transform:uppercase;color:var(--dm-text-muted,#888);",p.textContent="Preview";const f=document.createElement("iframe");f.src="/admin/preview/component-preview.html",f.style.cssText="width:100%;min-height:180px;border:1px solid var(--dm-border,rgba(255,255,255,.08));border-radius:4px;background:#fff;";const n=document.createElement("div");n.style.cssText="display:flex;justify-content:flex-end;gap:.5rem;margin-top:auto;padding-top:.75rem;border-top:1px solid var(--dm-border,rgba(255,255,255,.08));";const c=document.createElement("button");c.className="btn btn-ghost",c.textContent="Cancel";const a=document.createElement("button");a.className="btn btn-primary",a.textContent="Insert",a.disabled=!0,n.appendChild(c),n.appendChild(a),s.appendChild(o),s.appendChild(r),s.appendChild(l),s.appendChild(m),s.appendChild(p),s.appendChild(f),s.appendChild(n),i.setContent(s),i.open();let v=null,k={};function w(){r.replaceChildren();for(const y of d){const h=document.createElement("button");h.type="button",h.className="btn btn-ghost",h.style.cssText="display:flex;flex-direction:column;align-items:flex-start;gap:.25rem;padding:.6rem;border:1px solid var(--dm-border,rgba(255,255,255,.08));border-radius:4px;text-align:left;";const C=document.createElement("strong");C.style.cssText="font-size:.9rem;",C.textContent=y.name;const L=document.createElement("span");L.style.cssText="font-size:.72rem;color:var(--dm-text-muted,#888);",L.textContent=`${Object.keys(y.props||{}).length} prop(s)`,h.appendChild(C),h.appendChild(L),h.addEventListener("click",()=>x(y)),r.appendChild(h)}}function x(y){v=y,k={};for(const[h,C]of Object.entries(y.props||{}))k[h]=C.default!==void 0?C.default:"";a.disabled=!1,S(),M()}function S(){m.replaceChildren();const y=Object.entries(v.props||{});if(y.length===0){const h=document.createElement("p");h.className="text-muted",h.style.margin="0",h.textContent="This component takes no props.",m.appendChild(h);return}for(const[h,C]of y){const L=document.createElement("div");L.style.cssText="display:flex;align-items:center;gap:.5rem;margin-bottom:.4rem;";const N=document.createElement("label");N.style.cssText="font-size:.8rem;min-width:120px;color:var(--dm-text-muted,#aaa);",N.textContent=C.label||h,L.appendChild(N);const T=pe(C);ue(T,C,k[h]),T.addEventListener("input",()=>{k[h]=X(T,C),f.contentWindow?.postMessage({type:"update",payload:{props:k}},"*")}),T.addEventListener("change",()=>{k[h]=X(T,C),f.contentWindow?.postMessage({type:"update",payload:{props:k}},"*")}),L.appendChild(T),m.appendChild(L)}}async function M(){if(v)try{const y=await fetch(`/api/components/${encodeURIComponent(v.name)}.js`);if(!y.ok)throw new Error(`Failed to load component (${y.status})`);const h=await y.text();f.contentWindow?.postMessage({type:"remount",payload:{compiledJs:h,tagName:`dm-${v.name}`,props:k}},"*")}catch(y){E.toast(y.message||"Failed to load preview.",{type:"error"})}}c.addEventListener("click",()=>i.close()),a.addEventListener("click",()=>{if(!v)return;const y=t.selectionStart,h=t.selectionEnd,C=Object.entries(k).map(([N,T])=>{const R=N.replace(/([A-Z])/g,"-$1").toLowerCase(),B=String(T??"").replace(/"/g,""");return`${R}="${B}"`}).join(" "),L=`[component name="${v.name}"${C?" "+C:""} /]`;replaceRange(t,y,h,L),i.close()}),w()}function pe(t){let e;return t.type==="number"?(e=document.createElement("input"),e.type="number",e.className="form-input form-input--sm"):t.type==="boolean"?(e=document.createElement("input"),e.type="checkbox",e.className="form-check"):t.type==="array"||t.type==="object"?(e=document.createElement("textarea"),e.rows=2,e.className="form-input form-input--sm",e.style.fontFamily="var(--dm-font-mono, monospace)"):(e=document.createElement("input"),e.type="text",e.className="form-input form-input--sm"),e.style.flex="1",e}function X(t,e){if(e.type==="number")return t.value===""?null:Number(t.value);if(e.type==="boolean")return!!t.checked;if(e.type==="array"||e.type==="object")try{return JSON.parse(t.value||"null")}catch{return null}return t.value}function ue(t,e,d){e.type==="boolean"?t.checked=!!d:e.type==="array"||e.type==="object"?t.value=JSON.stringify(d??null):t.value=d??""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{openIconPicker as
|
|
1
|
+
import{openIconPicker as s}from"./card-builder.js";const i="display:block;font-size:.7rem;font-weight:600;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;margin-bottom:.25rem;",c="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;box-sizing:border-box;";export function makeField(r,t){const e=document.createElement("div"),n=document.createElement("label");return n.style.cssText=i,n.textContent=r,e.appendChild(n),e.appendChild(t),e}export function makeSelect(r){const t=document.createElement("select");return t.style.cssText=c,r.forEach(([e,n])=>{const o=document.createElement("option");o.value=e,o.textContent=n,t.appendChild(o)}),t}export function makeTextInput(r="",t=""){const e=document.createElement("input");return e.type="text",e.placeholder=r,e.value=t,e.style.cssText=c,e}export function makeCheckbox(r){const t=document.createElement("label");t.style.cssText="display:flex;align-items:center;gap:.5rem;cursor:pointer;";const e=document.createElement("input");e.type="checkbox";const n=document.createElement("span");return n.style.cssText="font-size:.85em;color:var(--dm-text,#eee);",n.textContent=r,t.appendChild(e),t.appendChild(n),t}export function makeIconInput(r="",t=""){const e=document.createElement("div");e.style.cssText="display:flex;gap:.35rem;";const n=makeTextInput(r,t);n.style.flex="1";const o=document.createElement("button");o.type="button",o.title="Browse icons";const a=document.createElement("span");return a.setAttribute("data-icon","grid"),a.setAttribute("data-icon-size","14"),a.style.cssText="display:inline-flex;align-items:center;vertical-align:middle;",o.appendChild(a),o.style.cssText="padding:.35rem .55rem;background:transparent;border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text-muted,#aaa);cursor:pointer;flex-shrink:0;display:inline-flex;align-items:center;",window.I?.scan?.(o),o.addEventListener("click",()=>s(d=>{n.value=d,n.dispatchEvent(new Event("input",{bubbles:!0}))})),e.appendChild(n),e.appendChild(o),{el:e,input:n}}export function makeLivePreview(){const r=document.createElement("pre");return r.style.cssText="background:var(--dm-background-alt,#111);border:1px solid var(--dm-border,#333);border-radius:4px;padding:.5rem .75rem;font-size:.75em;color:var(--dm-text-muted,#aaa);white-space:pre-wrap;word-break:break-all;margin:0;max-height:120px;overflow:auto;",r.textContent="",{el:r,update(t){r.textContent=t}}}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{openIconPicker as
|
|
1
|
+
import{openIconPicker as X}from"./card-builder.js";import{safeSetHTML as Z}from"./safe-html.js";function P(e){const t={};for(const[,i,l,o]of e.matchAll(/([\w-]+)=(?:"([^"]*)"|'([^']*)')/g))t[i]=l??o??"";const n=e.replace(/([\w-]+)=(?:"[^"]*"|'[^']*')/g,i=>" ".repeat(i.length));for(const[,i]of n.matchAll(/\b([\w-]+)\b/g))i in t||(t[i]=!0);return t}function h(e){return String(e).replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}const ee=new Set(["layout","theme","mode","id","class"]),te=new Set(["title","date","status","icon"]),ne=new Set(["slug","display","layout","theme","mode","title-field","date-field","status-field","icon-field","body-field","limit"]),M=["vertical","centred","horizontal"],q=["minimal","corporate","modern"],ie=["","planned","in-progress","completed","blocked"];let T=null,a=null,y=null,k=null,F=null,$=null,U=0;export const TimelineBuilder={open(e,t={}){if(T)return;y=e,k=t,a=j(),F=null;const n=parseTimelineAtCursor(e.value,e.selectionStart);n.found&&(F=n.range,a=n.state),re()},close(){N()}};function j(){const e=new Date().toISOString().slice(0,10);return{mode:"static",layout:"vertical",theme:"minimal",roadmap:!1,id:"",className:"",extras:{},events:[{title:"First Event",date:e,status:"completed",icon:"",body:"Describe this event.",extras:{}},{title:"Second Event",date:"",status:"planned",icon:"",body:"Describe this event.",extras:{}}],collection:{slug:"",titleField:"",dateField:"",statusField:"",iconField:"",bodyField:"",limit:""}}}export function parseTimelineAtCursor(e,t){let n=null;const i=/\[timeline([^\]]*)\]([\s\S]*?)\[\/timeline\]/gi;for(const s of e.matchAll(i)){const c=s.index,u=c+s[0].length;t>=c&&t<=u&&(!n||u-c<n.range.end-n.range.start)&&(n={kind:"static",range:{start:c,end:u},attrStr:s[1],body:s[2]})}const l=/\[collection([^\]]*?)\/\]/gi;for(const s of e.matchAll(l)){const c=s.index,u=c+s[0].length;if(t<c||t>u)continue;const w=P(s[1]);w.display==="timeline"&&(!n||u-c<n.range.end-n.range.start)&&(n={kind:"collection",range:{start:c,end:u},attrs:w})}if(!n)return{found:!1};if(n.kind==="static"){const s=P(n.attrStr),c={};Object.keys(s).forEach(g=>{!ee.has(g)&&s[g]!==!0&&(c[g]=s[g])});const u=[],w=/\[event([^\]]*)\]([\s\S]*?)\[\/event\]/gi;for(const g of n.body.matchAll(w)){const C=P(g[1]),p={};Object.keys(C).forEach(v=>{!te.has(v)&&C[v]!==!0&&(p[v]=C[v])}),u.push({title:C.title||"",date:C.date||"",status:C.status||"",icon:C.icon||"",body:g[2].trim(),extras:p})}return{found:!0,range:n.range,state:{mode:"static",layout:M.includes(s.layout)?s.layout:"vertical",theme:q.includes(s.theme)?s.theme:"minimal",roadmap:s.mode==="roadmap",id:s.id||"",className:s.class||"",extras:c,events:u.length?u:j().events,collection:j().collection}}}const o=n.attrs,m={};return Object.keys(o).forEach(s=>{!ne.has(s)&&o[s]!==!0&&(m[s]=o[s])}),{found:!0,range:n.range,state:{mode:"collection",layout:M.includes(o.layout)?o.layout:"vertical",theme:q.includes(o.theme)?o.theme:"minimal",roadmap:o.mode==="roadmap",id:"",className:"",extras:m,events:j().events,collection:{slug:o.slug||"",titleField:o["title-field"]||"",dateField:o["date-field"]||"",statusField:o["status-field"]||"",iconField:o["icon-field"]||"",bodyField:o["body-field"]||"",limit:o.limit||""}}}}function W(){return a.mode==="collection"?le():oe()}function oe(){const e=a,t=[];e.layout!=="vertical"&&t.push(`layout="${h(e.layout)}"`),e.theme!=="minimal"&&t.push(`theme="${h(e.theme)}"`),e.roadmap&&t.push('mode="roadmap"'),e.id&&t.push(`id="${h(e.id)}"`),e.className&&t.push(`class="${h(e.className)}"`),Object.entries(e.extras).forEach(([l,o])=>t.push(`${l}="${h(o)}"`));const n=t.length?" "+t.join(" "):"",i=e.events.map(l=>{const o=[];return l.title&&o.push(`title="${h(l.title)}"`),l.date&&o.push(`date="${h(l.date)}"`),l.status&&o.push(`status="${h(l.status)}"`),l.icon&&o.push(`icon="${h(l.icon)}"`),Object.entries(l.extras||{}).forEach(([s,c])=>o.push(`${s}="${h(c)}"`)),`[event${o.length?" "+o.join(" "):""}]
|
|
2
2
|
${(l.body||"").trim()}
|
|
3
3
|
[/event]`}).join(`
|
|
4
4
|
`);return`[timeline${n}]
|
|
5
5
|
${i}
|
|
6
|
-
[/timeline]`}function oe(){const e=a,t=e.collection,n=[`slug="${h(t.slug)}"`,'display="timeline"'];return e.layout!=="vertical"&&n.push(`layout="${h(e.layout)}"`),e.theme!=="minimal"&&n.push(`theme="${h(e.theme)}"`),e.roadmap&&n.push('mode="roadmap"'),t.titleField&&n.push(`title-field="${h(t.titleField)}"`),t.dateField&&n.push(`date-field="${h(t.dateField)}"`),t.statusField&&n.push(`status-field="${h(t.statusField)}"`),t.iconField&&n.push(`icon-field="${h(t.iconField)}"`),t.bodyField&&n.push(`body-field="${h(t.bodyField)}"`),t.limit&&n.push(`limit="${h(t.limit)}"`),Object.entries(e.extras).forEach(([i,l])=>n.push(`${i}="${h(l)}"`)),`[collection ${n.join(" ")} /]`}function z(){$&&(clearTimeout($),$=null),k&&(k.remove(),k=null,a=null,T=null)}function le(){const e=U();if(T){const{start:t,end:n}=T;y.value=y.value.slice(0,t)+e+y.value.slice(n),y.selectionStart=y.selectionEnd=t+e.length}else{const t=y.selectionStart,n=y.selectionEnd;y.value=y.value.slice(0,t)+e+y.value.slice(n),y.selectionStart=y.selectionEnd=t+e.length}y.dispatchEvent(new Event("input",{bubbles:!0})),y.focus(),z()}function d(e,t=""){const n=document.createElement(e);return t&&(n.style.cssText=t),n}const L="padding:7px 10px;border-radius:7px;border:1px solid var(--dm-border,#334155);background:var(--dm-surface,#0f172a);color:var(--dm-text,#e2e8f0);font-size:12px;font-family:inherit;width:100%",j="font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.07em;color:var(--dm-text-muted,#475569)";function S(e,t){const n=d("div","display:flex;flex-direction:column;gap:5px"),i=d("div",j);return i.textContent=e,n.appendChild(i),n.appendChild(t),n}function H(){return d("div","height:1px;background:var(--dm-border,#334155);margin:2px 0")}function de(){k=d("div","position:fixed;inset:0;background:rgba(0,0,0,.6);display:flex;align-items:center;justify-content:center;z-index:9999;padding:24px;isolation:isolate");const e=d("div","background:var(--dm-surface,#1e293b);border:1px solid var(--dm-border,#334155);border-radius:14px;width:100%;max-width:960px;max-height:90vh;display:flex;flex-direction:column;box-shadow:var(--dm-shadow-lg);overflow:hidden"),t=d("div","display:flex;align-items:center;justify-content:space-between;padding:14px 20px;border-bottom:1px solid var(--dm-border,#334155);flex-shrink:0"),n=d("span","font-weight:700;color:var(--dm-text,#f1f5f9);font-size:14px");n.textContent=T?"Edit Timeline":"Insert Timeline";const i=d("button","background:var(--dm-border,#334155);border:none;color:var(--dm-text-muted,#94a3b8);border-radius:6px;width:26px;height:26px;cursor:pointer;font-size:14px");i.textContent="\u2715",i.addEventListener("click",z),t.appendChild(n),t.appendChild(i);const l=d("div","display:grid;grid-template-columns:340px 1fr;flex:1;overflow:hidden");l.appendChild(ae()),l.appendChild(fe());const o=d("div","display:flex;justify-content:flex-end;gap:10px;padding:12px 20px;border-top:1px solid var(--dm-border,#334155);flex-shrink:0"),m=d("button","padding:8px 18px;border-radius:8px;border:none;background:var(--dm-border,#334155);color:var(--dm-text-muted,#94a3b8);font-size:12px;font-weight:700;cursor:pointer");m.textContent="Cancel",m.addEventListener("click",z);const s=d("button","padding:8px 18px;border-radius:8px;border:none;background:var(--dm-primary,#6366f1);color:var(--dm-primary-text,#fff);font-size:12px;font-weight:700;cursor:pointer");s.textContent=T?"Save Timeline":"Insert Timeline",s.addEventListener("click",le),o.appendChild(m),o.appendChild(s),e.appendChild(t),e.appendChild(l),e.appendChild(o),k.appendChild(e),k.addEventListener("click",c=>{c.target===k&&z()}),document.body.appendChild(k),x()}function ae(){const e=d("div","padding:18px;border-right:1px solid var(--dm-border,#334155);display:flex;flex-direction:column;gap:14px;overflow-y:auto");e.appendChild(re()),e.appendChild(H()),e.appendChild(S("Layout",V("layout",P.map(i=>[i,G(i)])))),e.appendChild(S("Theme",V("theme",M.map(i=>[i,G(i)])))),e.appendChild(S("Mode",se())),e.appendChild(H());const t=d("div","display:flex;flex-direction:column;gap:12px");t.id="tb-static",t.appendChild(ce()),e.appendChild(t);const n=d("div","display:flex;flex-direction:column;gap:12px");return n.id="tb-collection",n.appendChild(me()),e.appendChild(n),K(),e}function re(){const e=d("div","display:flex;gap:6px"),t=(n,i)=>{const l=d("button"),o=()=>{const m=a.mode===n;l.style.cssText=`flex:1;padding:8px 10px;border-radius:8px;border:1px solid;font-size:12px;font-weight:700;cursor:pointer;${m?"border-color:var(--dm-primary,#6366f1);background:color-mix(in srgb, var(--dm-primary,#6366f1) 15%, transparent);color:var(--dm-primary,#a5b4fc)":"border-color:var(--dm-border,#334155);background:var(--dm-surface,#0f172a);color:var(--dm-text-muted,#94a3b8)"}`};return l.type="button",l.textContent=i,o(),l.addEventListener("click",()=>{a.mode=n,e.querySelectorAll("button").forEach(m=>m._paint&&m._paint()),K(),x()}),l._paint=o,l};return e.appendChild(t("static","Static")),e.appendChild(t("collection","From Collection")),e}function K(){const e=document.getElementById("tb-static"),t=document.getElementById("tb-collection");e&&(e.style.display=a.mode==="static"?"":"none"),t&&(t.style.display=a.mode==="collection"?"":"none")}function V(e,t){const n=d("select",L+";cursor:pointer");return t.forEach(([i,l])=>{const o=document.createElement("option");o.value=i,o.textContent=l,i===a[e]&&(o.selected=!0),n.appendChild(o)}),n.addEventListener("change",()=>{a[e]=n.value,x()}),n}function se(){const e=d("label","display:flex;align-items:center;gap:.5rem;cursor:pointer;font-size:12px;color:var(--dm-text,#e2e8f0)"),t=document.createElement("input");return t.type="checkbox",t.checked=!!a.roadmap,t.addEventListener("change",()=>{a.roadmap=t.checked,x()}),e.appendChild(t),e.appendChild(document.createTextNode("Roadmap mode")),e}function ce(){const e=d("div","display:flex;flex-direction:column;gap:8px"),t=d("div","display:flex;align-items:center;justify-content:space-between"),n=d("div",j);n.textContent="Events";const i=d("button","padding:4px 10px;border-radius:6px;border:1px dashed var(--dm-border,#334155);background:transparent;color:var(--dm-text-muted,#94a3b8);font-size:11px;cursor:pointer");i.type="button",i.textContent="+ Add event",i.addEventListener("click",()=>{a.events.push({title:"New Event",date:"",status:"",icon:"",body:"",extras:{}}),N(),x()}),t.appendChild(n),t.appendChild(i),e.appendChild(t);const l=d("div","display:flex;flex-direction:column;gap:8px");return l.id="tb-events",e.appendChild(l),N(l),e}function N(e){const t=e||document.getElementById("tb-events");if(t){for(;t.firstChild;)t.removeChild(t.firstChild);a.events.forEach((n,i)=>t.appendChild(pe(n,i)))}}function pe(e,t){const n=d("div","border:1px solid var(--dm-border,#334155);border-radius:8px;padding:10px;background:var(--dm-background-alt,#0b1120);display:flex;flex-direction:column;gap:8px");n.draggable=!0,n.dataset.idx=String(t);const i=d("div","display:flex;align-items:center;gap:6px"),l=d("span","cursor:grab;color:var(--dm-text-muted,#475569);font-size:14px;user-select:none;padding:0 4px");l.textContent="\u2261",l.title="Drag to reorder",i.appendChild(l);const o=d("div","flex:1;font-size:12px;color:var(--dm-text,#e2e8f0);font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis");o.textContent=e.title||"(untitled event)",i.appendChild(o);const m=(r,f,b,E)=>{const _=d("button",`padding:2px 6px;border-radius:5px;border:1px solid var(--dm-border,#334155);background:transparent;color:var(--dm-text-muted,#94a3b8);font-size:11px;cursor:${E?"not-allowed":"pointer"};opacity:${E?"0.4":"1"}`);return _.type="button",_.title=f,_.textContent=r,E||_.addEventListener("click",b),_};i.appendChild(m("\u2191","Move up",()=>Y(t,-1),t===0)),i.appendChild(m("\u2193","Move down",()=>Y(t,1),t===a.events.length-1)),i.appendChild(m("\u2715","Delete",()=>ue(t),a.events.length<=1)),n.appendChild(i);const s=W(e.title,"Event title",r=>{e.title=r,o.textContent=r||"(untitled event)",x()});n.appendChild(A("Title",s));const c=d("div","display:grid;grid-template-columns:1fr 1fr;gap:6px"),u=document.createElement("input");u.type="date",u.value=e.date||"",u.style.cssText=L,u.addEventListener("input",()=>{e.date=u.value,x()}),c.appendChild(A("Date",u));const w=document.createElement("select");w.style.cssText=L+";cursor:pointer",ne.forEach(r=>{const f=document.createElement("option");f.value=r,f.textContent=r===""?"\u2014 none \u2014":G(r),r===e.status&&(f.selected=!0),w.appendChild(f)}),w.addEventListener("change",()=>{e.status=w.value,x()}),c.appendChild(A("Status",w)),n.appendChild(c);const g=d("div","display:flex;gap:6px"),C=W(e.icon,"e.g. rocket",r=>{e.icon=r,x()});C.style.flex="1";const p=d("button","padding:0 10px;background:var(--dm-border,#334155);border:none;color:var(--dm-text-muted,#94a3b8);border-radius:7px;font-size:12px;cursor:pointer;flex-shrink:0");p.type="button",p.title="Browse icons",p.textContent="\u2605",p.addEventListener("click",()=>Q(r=>{e.icon=r,C.value=r,x()})),g.appendChild(C),g.appendChild(p),n.appendChild(A("Icon",g));const v=document.createElement("textarea");return v.value=e.body||"",v.rows=2,v.style.cssText=L+";resize:vertical;min-height:48px;line-height:1.5",v.addEventListener("input",()=>{e.body=v.value,x()}),n.appendChild(A("Body (Markdown)",v)),n.addEventListener("dragstart",r=>{r.dataTransfer.effectAllowed="move",r.dataTransfer.setData("text/plain",String(t)),n.style.opacity="0.5"}),n.addEventListener("dragend",()=>{n.style.opacity=""}),n.addEventListener("dragover",r=>{r.preventDefault(),r.dataTransfer.dropEffect="move",n.style.borderColor="var(--dm-primary,#6366f1)"}),n.addEventListener("dragleave",()=>{n.style.borderColor="var(--dm-border,#334155)"}),n.addEventListener("drop",r=>{r.preventDefault(),n.style.borderColor="var(--dm-border,#334155)";const f=parseInt(r.dataTransfer.getData("text/plain"),10);if(Number.isNaN(f)||f===t)return;const[b]=a.events.splice(f,1);a.events.splice(t,0,b),N(),x()}),n}function Y(e,t){const n=e+t;if(n<0||n>=a.events.length)return;const[i]=a.events.splice(e,1);a.events.splice(n,0,i),N(),x()}function ue(e){a.events.length<=1||(a.events.splice(e,1),N(),x())}function W(e,t,n){const i=document.createElement("input");return i.type="text",i.value=e||"",i.placeholder=t||"",i.style.cssText=L,i.addEventListener("input",()=>n(i.value)),i}function A(e,t){const n=d("div","display:flex;flex-direction:column;gap:4px"),i=d("div","font-size:10px;font-weight:600;color:var(--dm-text-muted,#64748b);letter-spacing:.04em");return i.textContent=e,n.appendChild(i),n.appendChild(t),n}function me(){const e=d("div","display:flex;flex-direction:column;gap:10px"),t=d("select",L+";cursor:pointer"),n=document.createElement("option");n.value="",n.textContent="Loading collections\u2026",t.appendChild(n),e.appendChild(S("Collection",t));const i=B("titleField"),l=B("dateField"),o=B("statusField"),m=B("iconField"),s=B("bodyField");e.appendChild(S("Title field",i));const c=d("div","display:grid;grid-template-columns:1fr 1fr;gap:8px");c.appendChild(S("Date field",l)),c.appendChild(S("Status field",o)),e.appendChild(c),e.appendChild(S("Icon field",m)),e.appendChild(S("Body field",s));const u=W(a.collection.limit,"All",p=>{a.collection.limit=p,x()});u.type="number",u.min="1",e.appendChild(S("Limit (optional)",u));const w=d("div","font-size:11px;color:var(--dm-text-muted,#64748b);line-height:1.4");w.textContent="Picks entries in their default collection order. Set date, status, and icon fields to drive visual cues on the page.",e.appendChild(w);const g=p=>{[i,l,o,m,s].forEach(b=>{for(;b.firstChild;)b.removeChild(b.firstChild);const E=document.createElement("option");E.value="",E.textContent="\u2014 none \u2014",b.appendChild(E),p.forEach(_=>{const D=document.createElement("option");D.value=_.name,D.textContent=_.label||_.name,b.appendChild(D)})});const r=new Set(p.map(b=>b.name)),f=(b,E)=>{a.collection[b]&&r.has(a.collection[b])||(a.collection[b]=r.has(E)?E:"")};f("titleField","title"),f("dateField","date"),f("statusField","status"),f("iconField","icon"),f("bodyField","description"),i.value=a.collection.titleField,l.value=a.collection.dateField,o.value=a.collection.statusField,m.value=a.collection.iconField,s.value=a.collection.bodyField},C=async p=>{if(!p){g([]);return}try{const v=F.onGetCollection?await F.onGetCollection(p):null,r=v&&v.fields||[];g(r)}catch{g([])}};return t.addEventListener("change",()=>{a.collection.slug=t.value,C(t.value).then(x)}),(async()=>{let p=[];try{p=F.onListCollections?await F.onListCollections():[]}catch{p=[]}for(;t.firstChild;)t.removeChild(t.firstChild);if(!p.length){const r=document.createElement("option");r.value="",r.textContent="No collections available",t.appendChild(r),g([]);return}p.forEach(r=>{const f=document.createElement("option");f.value=r.slug,f.textContent=r.title||r.slug,t.appendChild(f)});const v=a.collection.slug;v&&p.some(r=>r.slug===v)?t.value=v:(a.collection.slug=p[0].slug,t.value=p[0].slug),await C(t.value),x()})(),e}function B(e){const t=d("select",L+";cursor:pointer"),n=document.createElement("option");return n.value="",n.textContent="\u2014 none \u2014",t.appendChild(n),t.addEventListener("change",()=>{a.collection[e]=t.value,x()}),t}function fe(){const e=d("div","padding:20px;background:var(--dm-surface,#0f172a);display:flex;flex-direction:column;gap:14px;overflow-y:auto"),t=d("div",j);t.textContent="Live Preview";const n=d("div","flex:1;min-height:160px;background:var(--dm-background-alt,#fff);border-radius:10px;padding:16px;color:var(--dm-text,#0f172a)");n.id="tb-preview-area";const i=d("div",j+";margin-bottom:4px");i.textContent="Shortcode";const l=d("pre","background:var(--dm-background-alt,#1e293b);border:1px solid var(--dm-border,#334155);border-radius:8px;padding:10px 14px;font-family:monospace;font-size:11px;color:var(--dm-primary,#a5b4fc);line-height:1.6;white-space:pre-wrap;word-break:break-word;max-height:160px;overflow:auto;margin:0");return l.id="tb-snippet",e.appendChild(t),e.appendChild(n),e.appendChild(i),e.appendChild(l),e}function x(){const e=document.getElementById("tb-snippet");e&&(e.textContent=U()),he()}function he(){$&&clearTimeout($),$=setTimeout(ve,300)}async function ve(){const e=document.getElementById("tb-preview-area");if(!e)return;const t=U(),n=++q;xe(e);try{const i=F.onPreview?await F.onPreview(t):null;if(n!==q)return;if(!i||typeof i.html!="string"){J(e);return}X(e,i.html),typeof I<"u"&&I.scan&&I.scan(e)}catch{if(n!==q)return;J(e)}}function xe(e){if(!e.dataset.loaded){for(;e.firstChild;)e.removeChild(e.firstChild);const t=d("div","color:var(--dm-text-muted,#94a3b8);font-size:12px");t.textContent="Rendering preview\u2026",e.appendChild(t),e.dataset.loaded="1"}}function J(e){for(;e.firstChild;)e.removeChild(e.firstChild);const t=d("div","color:var(--dm-text-muted,#94a3b8);font-size:12px;font-style:italic");t.textContent="Preview unavailable",e.appendChild(t)}function G(e){return e.charAt(0).toUpperCase()+e.slice(1)}
|
|
6
|
+
[/timeline]`}function le(){const e=a,t=e.collection,n=[`slug="${h(t.slug)}"`,'display="timeline"'];return e.layout!=="vertical"&&n.push(`layout="${h(e.layout)}"`),e.theme!=="minimal"&&n.push(`theme="${h(e.theme)}"`),e.roadmap&&n.push('mode="roadmap"'),t.titleField&&n.push(`title-field="${h(t.titleField)}"`),t.dateField&&n.push(`date-field="${h(t.dateField)}"`),t.statusField&&n.push(`status-field="${h(t.statusField)}"`),t.iconField&&n.push(`icon-field="${h(t.iconField)}"`),t.bodyField&&n.push(`body-field="${h(t.bodyField)}"`),t.limit&&n.push(`limit="${h(t.limit)}"`),Object.entries(e.extras).forEach(([i,l])=>n.push(`${i}="${h(l)}"`)),`[collection ${n.join(" ")} /]`}function N(){$&&(clearTimeout($),$=null),T&&(T.remove(),T=null,a=null,F=null)}function de(){const e=W();if(F){const{start:t,end:n}=F;y.value=y.value.slice(0,t)+e+y.value.slice(n),y.selectionStart=y.selectionEnd=t+e.length}else{const t=y.selectionStart,n=y.selectionEnd;y.value=y.value.slice(0,t)+e+y.value.slice(n),y.selectionStart=y.selectionEnd=t+e.length}y.dispatchEvent(new Event("input",{bubbles:!0})),y.focus(),N()}function d(e,t=""){const n=document.createElement(e);return t&&(n.style.cssText=t),n}function z(e,t,n=14){e.textContent="";const i=document.createElement("span");return i.setAttribute("data-icon",t),i.setAttribute("data-icon-size",String(n)),i.style.cssText="display:inline-flex;align-items:center;vertical-align:middle;",e.appendChild(i),typeof I<"u"&&I.scan&&I.scan(e),e}function ae(e,t,n,i=14){return z(e,t,i),e.appendChild(document.createTextNode(" "+n)),e}const L="padding:7px 10px;border-radius:7px;border:1px solid var(--dm-border,#334155);background:var(--dm-surface,#0f172a);color:var(--dm-text,#e2e8f0);font-size:12px;font-family:inherit;width:100%",D="font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.07em;color:var(--dm-text-muted,#475569)";function _(e,t){const n=d("div","display:flex;flex-direction:column;gap:5px"),i=d("div",D);return i.textContent=e,n.appendChild(i),n.appendChild(t),n}function K(){return d("div","height:1px;background:var(--dm-border,#334155);margin:2px 0")}function re(){T=d("div","position:fixed;inset:0;background:rgba(0,0,0,.6);display:flex;align-items:center;justify-content:center;z-index:9999;padding:24px;isolation:isolate");const e=d("div","background:var(--dm-surface,#1e293b);border:1px solid var(--dm-border,#334155);border-radius:14px;width:100%;max-width:960px;max-height:90vh;display:flex;flex-direction:column;box-shadow:var(--dm-shadow-lg);overflow:hidden"),t=d("div","display:flex;align-items:center;justify-content:space-between;padding:14px 20px;border-bottom:1px solid var(--dm-border,#334155);flex-shrink:0"),n=d("span","font-weight:700;color:var(--dm-text,#f1f5f9);font-size:14px");n.textContent=F?"Edit Timeline":"Insert Timeline";const i=d("button","background:var(--dm-border,#334155);border:none;color:var(--dm-text-muted,#94a3b8);border-radius:6px;width:26px;height:26px;cursor:pointer;font-size:14px");i.title="Close",z(i,"x"),i.addEventListener("click",N),t.appendChild(n),t.appendChild(i);const l=d("div","display:grid;grid-template-columns:340px 1fr;flex:1;overflow:hidden");l.appendChild(se()),l.appendChild(ve());const o=d("div","display:flex;justify-content:flex-end;gap:10px;padding:12px 20px;border-top:1px solid var(--dm-border,#334155);flex-shrink:0"),m=d("button","padding:8px 18px;border-radius:8px;border:none;background:var(--dm-border,#334155);color:var(--dm-text-muted,#94a3b8);font-size:12px;font-weight:700;cursor:pointer");m.textContent="Cancel",m.addEventListener("click",N);const s=d("button","padding:8px 18px;border-radius:8px;border:none;background:var(--dm-primary,#6366f1);color:var(--dm-primary-text,#fff);font-size:12px;font-weight:700;cursor:pointer");s.textContent=F?"Save Timeline":"Insert Timeline",s.addEventListener("click",de),o.appendChild(m),o.appendChild(s),e.appendChild(t),e.appendChild(l),e.appendChild(o),T.appendChild(e),T.addEventListener("click",c=>{c.target===T&&N()}),document.body.appendChild(T),x()}function se(){const e=d("div","padding:18px;border-right:1px solid var(--dm-border,#334155);display:flex;flex-direction:column;gap:14px;overflow-y:auto");e.appendChild(ce()),e.appendChild(K()),e.appendChild(_("Layout",Y("layout",M.map(i=>[i,H(i)])))),e.appendChild(_("Theme",Y("theme",q.map(i=>[i,H(i)])))),e.appendChild(_("Mode",pe())),e.appendChild(K());const t=d("div","display:flex;flex-direction:column;gap:12px");t.id="tb-static",t.appendChild(ue()),e.appendChild(t);const n=d("div","display:flex;flex-direction:column;gap:12px");return n.id="tb-collection",n.appendChild(he()),e.appendChild(n),V(),e}function ce(){const e=d("div","display:flex;gap:6px"),t=(n,i)=>{const l=d("button"),o=()=>{const m=a.mode===n;l.style.cssText=`flex:1;padding:8px 10px;border-radius:8px;border:1px solid;font-size:12px;font-weight:700;cursor:pointer;${m?"border-color:var(--dm-primary,#6366f1);background:color-mix(in srgb, var(--dm-primary,#6366f1) 15%, transparent);color:var(--dm-primary,#a5b4fc)":"border-color:var(--dm-border,#334155);background:var(--dm-surface,#0f172a);color:var(--dm-text-muted,#94a3b8)"}`};return l.type="button",l.textContent=i,o(),l.addEventListener("click",()=>{a.mode=n,e.querySelectorAll("button").forEach(m=>m._paint&&m._paint()),V(),x()}),l._paint=o,l};return e.appendChild(t("static","Static")),e.appendChild(t("collection","From Collection")),e}function V(){const e=document.getElementById("tb-static"),t=document.getElementById("tb-collection");e&&(e.style.display=a.mode==="static"?"":"none"),t&&(t.style.display=a.mode==="collection"?"":"none")}function Y(e,t){const n=d("select",L+";cursor:pointer");return t.forEach(([i,l])=>{const o=document.createElement("option");o.value=i,o.textContent=l,i===a[e]&&(o.selected=!0),n.appendChild(o)}),n.addEventListener("change",()=>{a[e]=n.value,x()}),n}function pe(){const e=d("label","display:flex;align-items:center;gap:.5rem;cursor:pointer;font-size:12px;color:var(--dm-text,#e2e8f0)"),t=document.createElement("input");return t.type="checkbox",t.checked=!!a.roadmap,t.addEventListener("change",()=>{a.roadmap=t.checked,x()}),e.appendChild(t),e.appendChild(document.createTextNode("Roadmap mode")),e}function ue(){const e=d("div","display:flex;flex-direction:column;gap:8px"),t=d("div","display:flex;align-items:center;justify-content:space-between"),n=d("div",D);n.textContent="Events";const i=d("button","padding:4px 10px;border-radius:6px;border:1px dashed var(--dm-border,#334155);background:transparent;color:var(--dm-text-muted,#94a3b8);font-size:11px;cursor:pointer");i.type="button",ae(i,"plus","Add event",12),i.addEventListener("click",()=>{a.events.push({title:"New Event",date:"",status:"",icon:"",body:"",extras:{}}),A(),x()}),t.appendChild(n),t.appendChild(i),e.appendChild(t);const l=d("div","display:flex;flex-direction:column;gap:8px");return l.id="tb-events",e.appendChild(l),A(l),e}function A(e){const t=e||document.getElementById("tb-events");if(t){for(;t.firstChild;)t.removeChild(t.firstChild);a.events.forEach((n,i)=>t.appendChild(me(n,i)))}}function me(e,t){const n=d("div","border:1px solid var(--dm-border,#334155);border-radius:8px;padding:10px;background:var(--dm-background-alt,#0b1120);display:flex;flex-direction:column;gap:8px");n.draggable=!0,n.dataset.idx=String(t);const i=d("div","display:flex;align-items:center;gap:6px"),l=d("span","cursor:grab;color:var(--dm-text-muted,#475569);font-size:14px;user-select:none;padding:0 4px");z(l,"menu"),l.title="Drag to reorder",i.appendChild(l);const o=d("div","flex:1;font-size:12px;color:var(--dm-text,#e2e8f0);font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis");o.textContent=e.title||"(untitled event)",i.appendChild(o);const m=(r,f,b,S)=>{const E=document.createElement("button");return E.type="button",E.className="btn btn-xs btn-ghost",E.style.cssText=`line-height:1;opacity:${S?".3":".6"};cursor:${S?"not-allowed":"pointer"};`,E.title=f,z(E,r),S||E.addEventListener("click",b),E};i.appendChild(m("arrow-up","Move up",()=>J(t,-1),t===0)),i.appendChild(m("arrow-down","Move down",()=>J(t,1),t===a.events.length-1)),i.appendChild(m("x","Delete",()=>fe(t),a.events.length<=1)),n.appendChild(i);const s=G(e.title,"Event title",r=>{e.title=r,o.textContent=r||"(untitled event)",x()});n.appendChild(B("Title",s));const c=d("div","display:grid;grid-template-columns:1fr 1fr;gap:6px"),u=document.createElement("input");u.type="date",u.value=e.date||"",u.style.cssText=L,u.addEventListener("input",()=>{e.date=u.value,x()}),c.appendChild(B("Date",u));const w=document.createElement("select");w.style.cssText=L+";cursor:pointer",ie.forEach(r=>{const f=document.createElement("option");f.value=r,f.textContent=r===""?"\u2014 none \u2014":H(r),r===e.status&&(f.selected=!0),w.appendChild(f)}),w.addEventListener("change",()=>{e.status=w.value,x()}),c.appendChild(B("Status",w)),n.appendChild(c);const g=d("div","display:flex;gap:6px"),C=G(e.icon,"e.g. rocket",r=>{e.icon=r,x()});C.style.flex="1";const p=d("button","padding:0 10px;background:var(--dm-border,#334155);border:none;color:var(--dm-text-muted,#94a3b8);border-radius:7px;font-size:12px;cursor:pointer;flex-shrink:0");p.type="button",p.title="Browse icons",z(p,"star"),p.addEventListener("click",()=>X(r=>{e.icon=r,C.value=r,x()})),g.appendChild(C),g.appendChild(p),n.appendChild(B("Icon",g));const v=document.createElement("textarea");return v.value=e.body||"",v.rows=2,v.style.cssText=L+";resize:vertical;min-height:48px;line-height:1.5",v.addEventListener("input",()=>{e.body=v.value,x()}),n.appendChild(B("Body (Markdown)",v)),n.addEventListener("dragstart",r=>{r.dataTransfer.effectAllowed="move",r.dataTransfer.setData("text/plain",String(t)),n.style.opacity="0.5"}),n.addEventListener("dragend",()=>{n.style.opacity=""}),n.addEventListener("dragover",r=>{r.preventDefault(),r.dataTransfer.dropEffect="move",n.style.borderColor="var(--dm-primary,#6366f1)"}),n.addEventListener("dragleave",()=>{n.style.borderColor="var(--dm-border,#334155)"}),n.addEventListener("drop",r=>{r.preventDefault(),n.style.borderColor="var(--dm-border,#334155)";const f=parseInt(r.dataTransfer.getData("text/plain"),10);if(Number.isNaN(f)||f===t)return;const[b]=a.events.splice(f,1);a.events.splice(t,0,b),A(),x()}),n}function J(e,t){const n=e+t;if(n<0||n>=a.events.length)return;const[i]=a.events.splice(e,1);a.events.splice(n,0,i),A(),x()}function fe(e){a.events.length<=1||(a.events.splice(e,1),A(),x())}function G(e,t,n){const i=document.createElement("input");return i.type="text",i.value=e||"",i.placeholder=t||"",i.style.cssText=L,i.addEventListener("input",()=>n(i.value)),i}function B(e,t){const n=d("div","display:flex;flex-direction:column;gap:4px"),i=d("div","font-size:10px;font-weight:600;color:var(--dm-text-muted,#64748b);letter-spacing:.04em");return i.textContent=e,n.appendChild(i),n.appendChild(t),n}function he(){const e=d("div","display:flex;flex-direction:column;gap:10px"),t=d("select",L+";cursor:pointer"),n=document.createElement("option");n.value="",n.textContent="Loading collections\u2026",t.appendChild(n),e.appendChild(_("Collection",t));const i=O("titleField"),l=O("dateField"),o=O("statusField"),m=O("iconField"),s=O("bodyField");e.appendChild(_("Title field",i));const c=d("div","display:grid;grid-template-columns:1fr 1fr;gap:8px");c.appendChild(_("Date field",l)),c.appendChild(_("Status field",o)),e.appendChild(c),e.appendChild(_("Icon field",m)),e.appendChild(_("Body field",s));const u=G(a.collection.limit,"All",p=>{a.collection.limit=p,x()});u.type="number",u.min="1",e.appendChild(_("Limit (optional)",u));const w=d("div","font-size:11px;color:var(--dm-text-muted,#64748b);line-height:1.4");w.textContent="Picks entries in their default collection order. Set date, status, and icon fields to drive visual cues on the page.",e.appendChild(w);const g=p=>{[i,l,o,m,s].forEach(b=>{for(;b.firstChild;)b.removeChild(b.firstChild);const S=document.createElement("option");S.value="",S.textContent="\u2014 none \u2014",b.appendChild(S),p.forEach(E=>{const R=document.createElement("option");R.value=E.name,R.textContent=E.label||E.name,b.appendChild(R)})});const r=new Set(p.map(b=>b.name)),f=(b,S)=>{a.collection[b]&&r.has(a.collection[b])||(a.collection[b]=r.has(S)?S:"")};f("titleField","title"),f("dateField","date"),f("statusField","status"),f("iconField","icon"),f("bodyField","description"),i.value=a.collection.titleField,l.value=a.collection.dateField,o.value=a.collection.statusField,m.value=a.collection.iconField,s.value=a.collection.bodyField},C=async p=>{if(!p){g([]);return}try{const v=k.onGetCollection?await k.onGetCollection(p):null,r=v&&v.fields||[];g(r)}catch{g([])}};return t.addEventListener("change",()=>{a.collection.slug=t.value,C(t.value).then(x)}),(async()=>{let p=[];try{p=k.onListCollections?await k.onListCollections():[]}catch{p=[]}for(;t.firstChild;)t.removeChild(t.firstChild);if(!p.length){const r=document.createElement("option");r.value="",r.textContent="No collections available",t.appendChild(r),g([]);return}p.forEach(r=>{const f=document.createElement("option");f.value=r.slug,f.textContent=r.title||r.slug,t.appendChild(f)});const v=a.collection.slug;v&&p.some(r=>r.slug===v)?t.value=v:(a.collection.slug=p[0].slug,t.value=p[0].slug),await C(t.value),x()})(),e}function O(e){const t=d("select",L+";cursor:pointer"),n=document.createElement("option");return n.value="",n.textContent="\u2014 none \u2014",t.appendChild(n),t.addEventListener("change",()=>{a.collection[e]=t.value,x()}),t}function ve(){const e=d("div","padding:20px;background:var(--dm-surface,#0f172a);display:flex;flex-direction:column;gap:14px;overflow-y:auto"),t=d("div",D);t.textContent="Live Preview";const n=d("div","flex:1;min-height:160px;background:var(--dm-background-alt,#fff);border-radius:10px;padding:16px;color:var(--dm-text,#0f172a)");n.id="tb-preview-area";const i=d("div",D+";margin-bottom:4px");i.textContent="Shortcode";const l=d("pre","background:var(--dm-background-alt,#1e293b);border:1px solid var(--dm-border,#334155);border-radius:8px;padding:10px 14px;font-family:monospace;font-size:11px;color:var(--dm-primary,#a5b4fc);line-height:1.6;white-space:pre-wrap;word-break:break-word;max-height:160px;overflow:auto;margin:0");return l.id="tb-snippet",e.appendChild(t),e.appendChild(n),e.appendChild(i),e.appendChild(l),e}function x(){const e=document.getElementById("tb-snippet");e&&(e.textContent=W()),xe()}function xe(){$&&clearTimeout($),$=setTimeout(ge,300)}async function ge(){const e=document.getElementById("tb-preview-area");if(!e)return;const t=W(),n=++U;be(e);try{const i=k.onPreview?await k.onPreview(t):null;if(n!==U)return;if(!i||typeof i.html!="string"){Q(e);return}Z(e,i.html),typeof I<"u"&&I.scan&&I.scan(e)}catch{if(n!==U)return;Q(e)}}function be(e){if(!e.dataset.loaded){for(;e.firstChild;)e.removeChild(e.firstChild);const t=d("div","color:var(--dm-text-muted,#94a3b8);font-size:12px");t.textContent="Rendering preview\u2026",e.appendChild(t),e.dataset.loaded="1"}}function Q(e){for(;e.firstChild;)e.removeChild(e.firstChild);const t=d("div","color:var(--dm-text-muted,#94a3b8);font-size:12px;font-style:italic");t.textContent="Preview unavailable",e.appendChild(t)}function H(e){return e.charAt(0).toUpperCase()+e.slice(1)}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{api as r}from"../api.js";import{filterByProject as
|
|
1
|
+
import{api as r}from"../api.js";import{filterByProject as p,getProjectFromHash as m}from"../lib/project-context.js";function a(o){return String(o).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}export const actionsListView={templateUrl:"/admin/js/templates/actions-list.html",async onMount(o){await l(o),o.find("#create-action-btn").off("click").on("click",()=>{R.navigate("/actions/new")}),Domma.icons.scan()}};async function l(o){let c=[];const d=E.loader(o.get(0),{type:"dots"});try{c=await r.actions.list(),o.find("#actions-pro-notice").hide()}catch(t){t.message?.includes("MongoDB")||t.message?.includes("pro mode")||t.message?.includes("connection")?o.find("#actions-pro-notice").show():E.toast("Could not load actions.",{type:"error"})}finally{d.destroy()}const i=m();i&&(c=p(c,i)),T.create("#actions-table",{data:c,columns:[{key:"title",title:"Title",render:(t,e)=>{const n=document.createElement("a");return n.href=`#/actions/edit/${a(e.slug)}`,n.textContent=t,n.style.fontWeight="600",n.outerHTML}},{key:"slug",title:"Slug",render:t=>`<code>${a(t)}</code>`},{key:"collection",title:"Collection",render:t=>`<code>${a(t||"\u2014")}</code>`},{key:"trigger",title:"Trigger",render:t=>a(t?.label||t?.type||"manual")},{key:"steps",title:"Steps",render:t=>String(Array.isArray(t)?t.length:0)},{key:"access",title:"Roles",render:t=>(t?.roles||[]).map(e=>`<span class="badge badge-secondary">${a(e)}</span>`).join(" ")},{key:"slug",title:"Actions",render:t=>{const e=document.createElement("div");e.style.cssText="display:flex;gap:.4rem;justify-content:flex-end;";const n=document.createElement("a");n.href=`#/actions/edit/${a(t)}`,n.className="btn btn-sm btn-ghost",n.setAttribute("data-tooltip","Edit"),n.innerHTML='<span data-icon="edit"></span>';const s=document.createElement("button");return s.className="btn btn-sm btn-danger js-delete-action",s.dataset.slug=t,s.setAttribute("data-tooltip","Delete"),s.innerHTML='<span data-icon="trash"></span>',e.appendChild(n),e.appendChild(s),e.outerHTML}}],emptyMessage:'No actions yet. Click "New Action" to create your first action.'}),document.querySelectorAll(".js-delete-action").forEach(t=>{t.addEventListener("click",async()=>{const e=t.dataset.slug;if(await E.confirm(`Delete action "${e}"? This cannot be undone.`))try{await r.actions.delete(e),E.toast("Action deleted.",{type:"success"}),await l(o)}catch{E.toast("Failed to delete action.",{type:"error"})}})}),Domma.icons.scan(),document.querySelectorAll("#actions-table [data-tooltip]").forEach(t=>{E.tooltip(t,{content:t.getAttribute("data-tooltip"),position:"top"})})}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{api as _}from"../api.js";const de=[["_eq","equals"],["_ne","not equal"],["_gt",">"],["_gte",">="],["_lt","<"],["_lte","<="],["_in","in list"],["_nin","not in list"],["_contains","contains"],["_starts","starts with"],["_ends","ends with"],["_exists","exists"]],be=["id","createdBy"],we=/\{\{\s*(params|query)\.([a-zA-Z_][a-zA-Z0-9_]*)\s*\}\}/g;function Se(C){const x=new Set;for(const n of Object.values(C?.filter||{}))if(typeof n=="string")for(const N of n.matchAll(we))N[1]==="query"&&x.add(N[2]);return[...x]}function je(C){return String(C??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}let O=null;function qe(C){for(const[x]of de)if(C.endsWith(x))return{field:C.slice(0,-x.length),op:x};return{field:C,op:"_eq"}}export const apiEndpointEditorView={templateUrl:"/admin/js/templates/api-endpoint-editor.html",async onMount(C){const x=C.get(0),n=e=>x.querySelector("#"+e)||document.getElementById(e),N=location.hash.split("?")[0].match(/\/api-endpoints\/edit\/([^/?#]+)/),q=N?decodeURIComponent(N[1]):null;n("ep-title").textContent=q?"Edit API Endpoint":"New API Endpoint",E.tabs(n("ep-editor-tabs"));const[pe,ue,me,u]=await Promise.all([_.projects.list().catch(()=>[]),_.collections.list().catch(()=>[]),_.get("/collections/roles/entries?limit=100").catch(()=>({entries:[]})),q?_.apiEndpoints.get(q).catch(()=>null):Promise.resolve(null)]);if(q&&!u){E.toast("Endpoint not found.",{type:"error"}),location.hash="#/api-endpoints";return}const fe=ue.filter(e=>!e.systemManaged&&!e.preset),ye=(me.entries||[]).map(e=>e.data?.name).filter(Boolean),k=n("endpoint-project");for(const e of pe){const t=document.createElement("option");t.value=e.slug,t.textContent=`${e.name} (${e.slug})`,k.appendChild(t)}const y=n("ep-collection");function G(e){return e.meta&&e.meta.project||"core"}function z(e){const t=e!==void 0?e:y.value,r=k.value,o=fe.filter(a=>{const s=G(a);return s===r||s==="core"});y.textContent="";for(const a of o){const s=document.createElement("option");s.value=a.slug,s.textContent=`${a.title} (${a.slug})${G(a)==="core"&&r!=="core"?" \u2014 core":""}`,y.appendChild(s)}if(!o.length){const a=document.createElement("option");a.value="",a.textContent="No collections available in this project",y.appendChild(a)}t&&[...y.options].some(a=>a.value===t)&&(y.value=t)}z();const L=n("ep-auth");for(const[e,t]of[["public","Public \u2014 no credentials"],["token","Token \u2014 project API token"]]){const r=document.createElement("option");r.value=e,r.textContent=t,L.appendChild(r)}for(const e of ye){const t=document.createElement("option");t.value=e,t.textContent=`Role: ${e}`,L.appendChild(t)}let T=[];async function R(){const e=y.value;if(T=[],e)try{T=((await _.collections.get(e))?.fields||[]).map(r=>r.name).filter(Boolean)}catch{}ee();for(const t of K.querySelectorAll(".ep-filter-row"))U(t.querySelector(".ep-f-field"));te()}function F(){return[...T,...be]}function ee(e=[]){const t=n("ep-fields-list");t.textContent="";for(const r of T){const o=document.createElement("label");o.style.cssText="display:flex;align-items:center;gap:.35rem;cursor:pointer;font-size:.9rem;";const a=document.createElement("input");a.type="checkbox",a.className="ep-field-cb",a.value=r,a.checked=e.includes(r),a.addEventListener("change",h),o.appendChild(a),o.appendChild(document.createTextNode(r)),t.appendChild(o)}if(!T.length){const r=document.createElement("p");r.className="text-muted",r.style.cssText="font-size:.85rem;margin:0;",r.textContent="No fields found on this collection.",t.appendChild(r)}}function te(e){const t=n("ep-sort"),r=e!==void 0?e:t.value;t.textContent="";for(const o of["createdAt",...F()]){const a=document.createElement("option");a.value=o==="createdAt"?"":o,a.textContent=o==="createdAt"?"createdAt (default)":o,t.appendChild(a)}t.value=r||""}function U(e,t){const r=t!==void 0?t:e.value;e.textContent="";for(const a of F()){const s=document.createElement("option");s.value=a,s.textContent=a,e.appendChild(s)}const o=document.createElement("option");if(o.value="__custom__",o.textContent="custom dot-path\u2026",e.appendChild(o),r&&[...e.options].some(a=>a.value===r))e.value=r;else if(r){const a=document.createElement("option");a.value=r,a.textContent=r,e.insertBefore(a,o),e.value=r}}const K=n("ep-filter-rows");function M(e="",t="_eq",r=""){const o=document.createElement("div");o.className="ep-filter-row",o.style.cssText="display:grid;grid-template-columns:2fr 1.2fr 2fr auto;gap:.5rem;margin-bottom:.5rem;align-items:center;";const a=document.createElement("select");a.className="form-input ep-f-field",U(a,e||void 0),a.addEventListener("change",()=>{if(a.value==="__custom__"){const i=prompt("Dot-path field (e.g. address.city):","");i&&i.trim()?U(a,i.trim()):a.value=F()[0]||""}h()});const s=document.createElement("select");s.className="form-input ep-f-op";for(const[i,j]of de){const w=document.createElement("option");w.value=i,w.textContent=j,s.appendChild(w)}s.value=t,s.addEventListener("change",h);const c=document.createElement("input");c.type="text",c.className="form-input ep-f-value",c.placeholder="e.g. {{params.date}} or {{query.team}} or a literal",c.value=r,c.addEventListener("input",h);const d=document.createElement("button");d.className="btn btn-sm btn-ghost",d.innerHTML='<span data-icon="trash"></span>',d.addEventListener("click",()=>{o.remove(),h()}),o.appendChild(a),o.appendChild(s),o.appendChild(c),o.appendChild(d),K.appendChild(o),Domma.icons.scan(o)}function he(){const e={};for(const t of K.querySelectorAll(".ep-filter-row")){const r=t.querySelector(".ep-f-field").value,o=t.querySelector(".ep-f-op").value,a=t.querySelector(".ep-f-value").value;!r||r==="__custom__"||(e[o==="_eq"?r:r+o]=a)}return e}function I(){return{name:n("ep-name").value.trim(),project:k.value,path:n("ep-path").value.trim(),collection:y.value,auth:L.value,mode:n("ep-mode").value,filter:he(),sort:n("ep-sort").value||null,order:n("ep-order").value,limit:parseInt(n("ep-limit").value,10)||0,fields:[...x.querySelectorAll(".ep-field-cb:checked")].map(e=>e.value),enabled:n("ep-enabled").checked}}let B=null,v=null;function D(){return!B||JSON.stringify(I())!==B}function h(){ne(),Z()}function ne(){n("ep-url-preview").textContent=`/api/x/${k.value||"<project>"}${n("ep-path").value||"/\u2026"}`}function ve(e){return(e.match(/:([a-zA-Z_][a-zA-Z0-9_]*)/g)||[]).map(t=>t.slice(1))}function Z(){const e=D();n("tryit-dirty-note").style.display=e?"":"none",n("tryit-send").disabled=e,n("tryit-token-group").style.display=v?.auth==="token"?"":"none";const t=n("tryit-params"),r={};for(const s of t.querySelectorAll("input"))r[s.dataset.param]=s.value;t.textContent="";for(const s of ve(v?.path||"")){const c=document.createElement("div");c.className="form-group";const d=document.createElement("label");d.className="form-label",d.textContent=`:${s}`;const i=document.createElement("input");i.type="text",i.className="form-input",i.dataset.param=s,i.value=r[s]||"",c.appendChild(d),c.appendChild(i),t.appendChild(c)}const o=n("tryit-query-params"),a={};for(const s of o.querySelectorAll("input"))a[s.dataset.queryParam]=s.value;o.textContent="";for(const s of Se(v)){const c=document.createElement("div");c.className="form-group";const d=document.createElement("label");d.className="form-label",d.textContent=`?${s}`;const i=document.createElement("input");i.type="text",i.className="form-input",i.dataset.queryParam=s,i.value=a[s]||"",i.placeholder=`optional \u2014 filters by ${s}`,c.appendChild(d),c.appendChild(i),o.appendChild(c)}}let J="";const W=`apitryit:hist:${q||"new"}`,ge=12;function oe(){const e=S.get(W);return Array.isArray(e)?e:[]}function ae(e){const t=oe().filter(o=>o.url!==e.url),r=[e,...t].slice(0,ge);S.set(W,r),Y()}function Ee(e){for(const t of n("tryit-params").querySelectorAll("input"))t.value=e.params?.[t.dataset.param]??"";for(const t of n("tryit-query-params").querySelectorAll("input"))t.value=e.queryParams?.[t.dataset.queryParam]??"";n("tryit-query").value=e.extra||"",Q()}function Y(){const e=n("tryit-history-list"),t=n("tryit-history-card");if(!e||!t)return;const r=oe();t.style.display=r.length?"":"none",e.textContent="";for(const o of r){const a=document.createElement("button");a.type="button",a.className="btn btn-ghost btn-sm",a.style.cssText="display:flex;align-items:center;gap:.5rem;width:100%;justify-content:flex-start;text-align:left;font-family:var(--dm-font-mono,monospace);font-size:.78rem;padding:.35rem .5rem;";const s=document.createElement("span"),c=o.ok;s.className="badge "+(c?"badge-success":o.status>=500||o.status===0?"badge-danger":"badge-warning"),s.style.cssText="flex:0 0 auto;",s.textContent=o.status||"ERR";const d=document.createElement("span");d.style.cssText="flex:1 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;",d.textContent=o.url.replace(`/api/x/${v?.project||""}`,"")||o.url,d.title=o.url,a.appendChild(s),a.appendChild(d),a.addEventListener("click",()=>Ee(o)),e.appendChild(a)}}const m={key:"var(--dm-info)",index:"var(--dm-text-muted)",string:"var(--dm-success)",number:"var(--dm-warning-dark)",boolean:"var(--dm-secondary)",nul:"var(--dm-danger)",punc:"var(--dm-text-muted)",preview:"var(--dm-text-muted)"};function f(e,t,r){const o=document.createElement("span");return o.style.color=e,r&&(o.style.cssText+=";"+r),o.textContent=t,o}function re(e,t){return t?f(m.index,String(e)):f(m.key,JSON.stringify(String(e)))}function Ce(e){return e===null?f(m.nul,"null"):typeof e=="string"?f(m.string,JSON.stringify(e)):typeof e=="number"?f(m.number,String(e)):typeof e=="boolean"?f(m.boolean,String(e)):f(m.string,JSON.stringify(e))}function se(e,t,r){const o=e&&typeof e=="object",a=o&&(Array.isArray(e)?e.length===0:Object.keys(e).length===0);if(!o||a){const p=document.createElement("div");return p.style.cssText="white-space:pre-wrap;word-break:break-word;padding-left:1.2em;",t!==void 0&&(p.appendChild(re(t,r)),p.appendChild(f(m.punc,": "))),p.appendChild(o?f(m.punc,Array.isArray(e)?"[]":"{}"):Ce(e)),p}const s=Array.isArray(e),c=s?e.map((p,b)=>[b,p,!0]):Object.entries(e).map(([p,b])=>[p,b,!1]),d=document.createElement("div"),i=document.createElement("div");i.style.cssText="white-space:pre-wrap;cursor:pointer;";const j=f(m.punc,"\u25BE","display:inline-block;width:1.2em;");i.appendChild(j),t!==void 0&&(i.appendChild(re(t,r)),i.appendChild(f(m.punc,": "))),i.appendChild(f(m.punc,s?"[":"{"));const w=f(m.preview,` ${c.length} ${s?"item":"key"}${c.length===1?"":"s"} `,"font-style:italic;"),P=f(m.punc,s?"]":"}");i.appendChild(w),i.appendChild(P),d.appendChild(i);const A=document.createElement("div");A.style.cssText="padding-left:1.2em;border-left:1px solid var(--dm-border-light);";for(const[p,b,X]of c)A.appendChild(se(b,p,X));d.appendChild(A);const $=document.createElement("div");$.style.paddingLeft="1.2em",$.appendChild(f(m.punc,s?"]":"}")),d.appendChild($);let l=!1;const g=p=>{l=p,j.textContent=p?"\u25B8":"\u25BE",w.style.display=p?"":"none",P.style.display=p?"":"none",A.style.display=p?"none":"",$.style.display=p?"none":""};return g(!1),i.addEventListener("click",()=>g(!l)),d}let V="";function ie(e){n("tryit-json").style.display=e?"":"none",n("tryit-body").style.display=e?"none":"",n("tryit-json-toggle").textContent=e?"Raw":"Tree"}function le(e){V=e;const t=n("tryit-results-placeholder");t&&(t.style.display="none"),n("tryit-response-card").style.display="";let r,o=!0;try{r=JSON.parse(e)}catch{o=!1}n("tryit-body").textContent=o?JSON.stringify(r,null,2):e;const a=n("tryit-json");a.textContent="",o&&a.appendChild(se(r)),n("tryit-json-toggle").style.display=o?"":"none",ie(o)}async function Q(){if(!v)return;const e={},t={};let r=v.path;for(const l of n("tryit-params").querySelectorAll("input")){e[l.dataset.param]=l.value;const g=new RegExp(":"+l.dataset.param.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")+"(?=/|$)","g");r=r.replace(g,encodeURIComponent(l.value))}const o=[];for(const l of n("tryit-query-params").querySelectorAll("input")){const g=l.value.trim();t[l.dataset.queryParam]=l.value,g&&o.push(`${encodeURIComponent(l.dataset.queryParam)}=${encodeURIComponent(g)}`)}const a=n("tryit-query").value.trim();a&&o.push(a);const s=o.join("&"),c=`/api/x/${v.project}${r}${s?"?"+s:""}`,d={ts:Date.now(),url:c,params:e,queryParams:t,extra:a},i={},j=n("tryit-token").value.trim();v.auth==="token"&&j&&(i.Authorization=`Bearer ${j}`);const w=location.origin+c,P=l=>`'${String(l).replace(/'/g,"'\\''")}'`,A=[`curl ${P(w)}`];for(const[l,g]of Object.entries(i))A.push(` -H ${P(`${l}: ${g}`)}`);J=A.join(` \\
|
|
2
|
-
`),n("tryit-result").style.display="",n("tryit-curl").textContent=J;const $=n("tryit-send");$.disabled=!0;try{const l=await fetch(c,{headers:i}),
|
|
3
|
-
`):"(none exposed)",
|
|
1
|
+
import{api as _}from"../api.js";const pe=[["_eq","equals"],["_ne","not equal"],["_gt",">"],["_gte",">="],["_lt","<"],["_lte","<="],["_in","in list"],["_nin","not in list"],["_contains","contains"],["_starts","starts with"],["_ends","ends with"],["_exists","exists"]],we=["id","createdBy"],Se=/\{\{\s*(params|query)\.([a-zA-Z_][a-zA-Z0-9_]*)\s*\}\}/g;function qe(x){const v=new Set;for(const n of Object.values(x?.filter||{}))if(typeof n=="string")for(const N of n.matchAll(Se))N[1]==="query"&&v.add(N[2]);return[...v]}function Ae(x){return String(x??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}let O=null;function ke(x){for(const[v]of pe)if(x.endsWith(v))return{field:x.slice(0,-v.length),op:v};return{field:x,op:"_eq"}}export const apiEndpointEditorView={templateUrl:"/admin/js/templates/api-endpoint-editor.html",async onMount(x){const v=x.get(0),n=e=>v.querySelector("#"+e)||document.getElementById(e),N=location.hash.split("?")[0].match(/\/api-endpoints\/edit\/([^/?#]+)/),q=N?decodeURIComponent(N[1]):null;n("ep-title").textContent=q?"Edit API Endpoint":"New API Endpoint",E.tabs(n("ep-editor-tabs"));const G=E.loader(v,{type:"dots"}),[ue,me,fe,u]=await Promise.all([_.projects.list().catch(()=>[]),_.collections.list().catch(()=>[]),_.get("/collections/roles/entries?limit=100").catch(()=>({entries:[]})),q?_.apiEndpoints.get(q).catch(()=>null):Promise.resolve(null)]);if(q&&!u){G.destroy(),E.toast("Endpoint not found.",{type:"error"}),location.hash="#/api-endpoints";return}const ye=me.filter(e=>!e.systemManaged&&!e.preset),he=(fe.entries||[]).map(e=>e.data?.name).filter(Boolean),k=n("endpoint-project");for(const e of ue){const t=document.createElement("option");t.value=e.slug,t.textContent=`${e.name} (${e.slug})`,k.appendChild(t)}const y=n("ep-collection");function ee(e){return e.meta&&e.meta.project||"core"}function z(e){const t=e!==void 0?e:y.value,r=k.value,o=ye.filter(a=>{const s=ee(a);return s===r||s==="core"});y.textContent="";for(const a of o){const s=document.createElement("option");s.value=a.slug,s.textContent=`${a.title} (${a.slug})${ee(a)==="core"&&r!=="core"?" \u2014 core":""}`,y.appendChild(s)}if(!o.length){const a=document.createElement("option");a.value="",a.textContent="No collections available in this project",y.appendChild(a)}t&&[...y.options].some(a=>a.value===t)&&(y.value=t)}z();const L=n("ep-auth");for(const[e,t]of[["public","Public \u2014 no credentials"],["token","Token \u2014 project API token"]]){const r=document.createElement("option");r.value=e,r.textContent=t,L.appendChild(r)}for(const e of he){const t=document.createElement("option");t.value=e,t.textContent=`Role: ${e}`,L.appendChild(t)}let T=[];async function R(){const e=y.value;if(T=[],e)try{T=((await _.collections.get(e))?.fields||[]).map(r=>r.name).filter(Boolean)}catch{}te();for(const t of K.querySelectorAll(".ep-filter-row"))U(t.querySelector(".ep-f-field"));ne()}function F(){return[...T,...we]}function te(e=[]){const t=n("ep-fields-list");t.textContent="";for(const r of T){const o=document.createElement("label");o.style.cssText="display:flex;align-items:center;gap:.35rem;cursor:pointer;font-size:.9rem;";const a=document.createElement("input");a.type="checkbox",a.className="ep-field-cb",a.value=r,a.checked=e.includes(r),a.addEventListener("change",h),o.appendChild(a),o.appendChild(document.createTextNode(r)),t.appendChild(o)}if(!T.length){const r=document.createElement("p");r.className="text-muted",r.style.cssText="font-size:.85rem;margin:0;",r.textContent="No fields found on this collection.",t.appendChild(r)}}function ne(e){const t=n("ep-sort"),r=e!==void 0?e:t.value;t.textContent="";for(const o of["createdAt",...F()]){const a=document.createElement("option");a.value=o==="createdAt"?"":o,a.textContent=o==="createdAt"?"createdAt (default)":o,t.appendChild(a)}t.value=r||""}function U(e,t){const r=t!==void 0?t:e.value;e.textContent="";for(const a of F()){const s=document.createElement("option");s.value=a,s.textContent=a,e.appendChild(s)}const o=document.createElement("option");if(o.value="__custom__",o.textContent="custom dot-path\u2026",e.appendChild(o),r&&[...e.options].some(a=>a.value===r))e.value=r;else if(r){const a=document.createElement("option");a.value=r,a.textContent=r,e.insertBefore(a,o),e.value=r}}const K=n("ep-filter-rows");function M(e="",t="_eq",r=""){const o=document.createElement("div");o.className="ep-filter-row",o.style.cssText="display:grid;grid-template-columns:2fr 1.2fr 2fr auto;gap:.5rem;margin-bottom:.5rem;align-items:center;";const a=document.createElement("select");a.className="form-input ep-f-field",U(a,e||void 0),a.addEventListener("change",()=>{if(a.value==="__custom__"){const i=prompt("Dot-path field (e.g. address.city):","");i&&i.trim()?U(a,i.trim()):a.value=F()[0]||""}h()});const s=document.createElement("select");s.className="form-input ep-f-op";for(const[i,j]of pe){const w=document.createElement("option");w.value=i,w.textContent=j,s.appendChild(w)}s.value=t,s.addEventListener("change",h);const c=document.createElement("input");c.type="text",c.className="form-input ep-f-value",c.placeholder="e.g. {{params.date}} or {{query.team}} or a literal",c.value=r,c.addEventListener("input",h);const d=document.createElement("button");d.className="btn btn-sm btn-ghost",d.innerHTML='<span data-icon="trash"></span>',d.addEventListener("click",()=>{o.remove(),h()}),o.appendChild(a),o.appendChild(s),o.appendChild(c),o.appendChild(d),K.appendChild(o),Domma.icons.scan(o)}function ve(){const e={};for(const t of K.querySelectorAll(".ep-filter-row")){const r=t.querySelector(".ep-f-field").value,o=t.querySelector(".ep-f-op").value,a=t.querySelector(".ep-f-value").value;!r||r==="__custom__"||(e[o==="_eq"?r:r+o]=a)}return e}function I(){return{name:n("ep-name").value.trim(),project:k.value,path:n("ep-path").value.trim(),collection:y.value,auth:L.value,mode:n("ep-mode").value,filter:ve(),sort:n("ep-sort").value||null,order:n("ep-order").value,limit:parseInt(n("ep-limit").value,10)||0,fields:[...v.querySelectorAll(".ep-field-cb:checked")].map(e=>e.value),enabled:n("ep-enabled").checked}}let B=null,g=null;function D(){return!B||JSON.stringify(I())!==B}function h(){oe(),Z()}function oe(){n("ep-url-preview").textContent=`/api/x/${k.value||"<project>"}${n("ep-path").value||"/\u2026"}`}function ge(e){return(e.match(/:([a-zA-Z_][a-zA-Z0-9_]*)/g)||[]).map(t=>t.slice(1))}function Z(){const e=D();n("tryit-dirty-note").style.display=e?"":"none",n("tryit-send").disabled=e,n("tryit-token-group").style.display=g?.auth==="token"?"":"none";const t=n("tryit-params"),r={};for(const s of t.querySelectorAll("input"))r[s.dataset.param]=s.value;t.textContent="";for(const s of ge(g?.path||"")){const c=document.createElement("div");c.className="form-group";const d=document.createElement("label");d.className="form-label",d.textContent=`:${s}`;const i=document.createElement("input");i.type="text",i.className="form-input",i.dataset.param=s,i.value=r[s]||"",c.appendChild(d),c.appendChild(i),t.appendChild(c)}const o=n("tryit-query-params"),a={};for(const s of o.querySelectorAll("input"))a[s.dataset.queryParam]=s.value;o.textContent="";for(const s of qe(g)){const c=document.createElement("div");c.className="form-group";const d=document.createElement("label");d.className="form-label",d.textContent=`?${s}`;const i=document.createElement("input");i.type="text",i.className="form-input",i.dataset.queryParam=s,i.value=a[s]||"",i.placeholder=`optional \u2014 filters by ${s}`,c.appendChild(d),c.appendChild(i),o.appendChild(c)}}let J="";const W=`apitryit:hist:${q||"new"}`,Ee=12;function ae(){const e=S.get(W);return Array.isArray(e)?e:[]}function re(e){const t=ae().filter(o=>o.url!==e.url),r=[e,...t].slice(0,Ee);S.set(W,r),Y()}function Ce(e){for(const t of n("tryit-params").querySelectorAll("input"))t.value=e.params?.[t.dataset.param]??"";for(const t of n("tryit-query-params").querySelectorAll("input"))t.value=e.queryParams?.[t.dataset.queryParam]??"";n("tryit-query").value=e.extra||"",Q()}function Y(){const e=n("tryit-history-list"),t=n("tryit-history-card");if(!e||!t)return;const r=ae();t.style.display=r.length?"":"none",e.textContent="";for(const o of r){const a=document.createElement("button");a.type="button",a.className="btn btn-ghost btn-sm",a.style.cssText="display:flex;align-items:center;gap:.5rem;width:100%;justify-content:flex-start;text-align:left;font-family:var(--dm-font-mono,monospace);font-size:.78rem;padding:.35rem .5rem;";const s=document.createElement("span"),c=o.ok;s.className="badge "+(c?"badge-success":o.status>=500||o.status===0?"badge-danger":"badge-warning"),s.style.cssText="flex:0 0 auto;",s.textContent=o.status||"ERR";const d=document.createElement("span");d.style.cssText="flex:1 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;",d.textContent=o.url.replace(`/api/x/${g?.project||""}`,"")||o.url,d.title=o.url,a.appendChild(s),a.appendChild(d),a.addEventListener("click",()=>Ce(o)),e.appendChild(a)}}const m={key:"var(--dm-info)",index:"var(--dm-text-muted)",string:"var(--dm-success)",number:"var(--dm-warning-dark)",boolean:"var(--dm-secondary)",nul:"var(--dm-danger)",punc:"var(--dm-text-muted)",preview:"var(--dm-text-muted)"};function f(e,t,r){const o=document.createElement("span");return o.style.color=e,r&&(o.style.cssText+=";"+r),o.textContent=t,o}function se(e,t){return t?f(m.index,String(e)):f(m.key,JSON.stringify(String(e)))}function xe(e){return e===null?f(m.nul,"null"):typeof e=="string"?f(m.string,JSON.stringify(e)):typeof e=="number"?f(m.number,String(e)):typeof e=="boolean"?f(m.boolean,String(e)):f(m.string,JSON.stringify(e))}function ie(e,t,r){const o=e&&typeof e=="object",a=o&&(Array.isArray(e)?e.length===0:Object.keys(e).length===0);if(!o||a){const p=document.createElement("div");return p.style.cssText="white-space:pre-wrap;word-break:break-word;padding-left:1.2em;",t!==void 0&&(p.appendChild(se(t,r)),p.appendChild(f(m.punc,": "))),p.appendChild(o?f(m.punc,Array.isArray(e)?"[]":"{}"):xe(e)),p}const s=Array.isArray(e),c=s?e.map((p,b)=>[b,p,!0]):Object.entries(e).map(([p,b])=>[p,b,!1]),d=document.createElement("div"),i=document.createElement("div");i.style.cssText="white-space:pre-wrap;cursor:pointer;";const j=f(m.punc,"\u25BE","display:inline-block;width:1.2em;");i.appendChild(j),t!==void 0&&(i.appendChild(se(t,r)),i.appendChild(f(m.punc,": "))),i.appendChild(f(m.punc,s?"[":"{"));const w=f(m.preview,` ${c.length} ${s?"item":"key"}${c.length===1?"":"s"} `,"font-style:italic;"),P=f(m.punc,s?"]":"}");i.appendChild(w),i.appendChild(P),d.appendChild(i);const A=document.createElement("div");A.style.cssText="padding-left:1.2em;border-left:1px solid var(--dm-border-light);";for(const[p,b,X]of c)A.appendChild(ie(b,p,X));d.appendChild(A);const $=document.createElement("div");$.style.paddingLeft="1.2em",$.appendChild(f(m.punc,s?"]":"}")),d.appendChild($);let l=!1;const C=p=>{l=p,j.textContent=p?"\u25B8":"\u25BE",w.style.display=p?"":"none",P.style.display=p?"":"none",A.style.display=p?"none":"",$.style.display=p?"none":""};return C(!1),i.addEventListener("click",()=>C(!l)),d}let V="";function le(e){n("tryit-json").style.display=e?"":"none",n("tryit-body").style.display=e?"none":"",n("tryit-json-toggle").textContent=e?"Raw":"Tree"}function ce(e){V=e;const t=n("tryit-results-placeholder");t&&(t.style.display="none"),n("tryit-response-card").style.display="";let r,o=!0;try{r=JSON.parse(e)}catch{o=!1}n("tryit-body").textContent=o?JSON.stringify(r,null,2):e;const a=n("tryit-json");a.textContent="",o&&a.appendChild(ie(r)),n("tryit-json-toggle").style.display=o?"":"none",le(o)}async function Q(){if(!g)return;const e={},t={};let r=g.path;for(const l of n("tryit-params").querySelectorAll("input")){e[l.dataset.param]=l.value;const C=new RegExp(":"+l.dataset.param.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")+"(?=/|$)","g");r=r.replace(C,encodeURIComponent(l.value))}const o=[];for(const l of n("tryit-query-params").querySelectorAll("input")){const C=l.value.trim();t[l.dataset.queryParam]=l.value,C&&o.push(`${encodeURIComponent(l.dataset.queryParam)}=${encodeURIComponent(C)}`)}const a=n("tryit-query").value.trim();a&&o.push(a);const s=o.join("&"),c=`/api/x/${g.project}${r}${s?"?"+s:""}`,d={ts:Date.now(),url:c,params:e,queryParams:t,extra:a},i={},j=n("tryit-token").value.trim();g.auth==="token"&&j&&(i.Authorization=`Bearer ${j}`);const w=location.origin+c,P=l=>`'${String(l).replace(/'/g,"'\\''")}'`,A=[`curl ${P(w)}`];for(const[l,C]of Object.entries(i))A.push(` -H ${P(`${l}: ${C}`)}`);J=A.join(` \\
|
|
2
|
+
`),n("tryit-result").style.display="",n("tryit-curl").textContent=J;const $=n("tryit-send");$.disabled=!0;try{const l=await fetch(c,{headers:i}),C=await l.text(),p=n("tryit-status");p.textContent=`${l.status} ${l.statusText}`,p.className="badge "+(l.ok?"badge-success":l.status>=500?"badge-danger":"badge-warning");const b=[];l.headers.forEach((X,be)=>b.push(`${be}: ${X}`)),n("tryit-headers-group").style.display="",n("tryit-headers").textContent=b.length?b.join(`
|
|
3
|
+
`):"(none exposed)",ce(C),re({...d,status:l.status,statusText:l.statusText,ok:l.ok})}catch(l){n("tryit-status").textContent="Network error",n("tryit-status").className="badge badge-danger",n("tryit-headers-group").style.display="none",ce(String(l.message||l)),re({...d,status:0,statusText:"Network error",ok:!1})}finally{$.disabled=D()}}if(u){if(n("ep-name").value=u.name||"",k.value=u.project,k.disabled=!0,n("ep-path").value=u.path||"",z(u.collection),y.value!==u.collection){const e=document.createElement("option");e.value=u.collection,e.textContent=`${u.collection} (other project \u2014 no longer allowed)`,y.appendChild(e),y.value=u.collection}L.value=u.auth||"public",n("ep-mode").value=u.mode||"list",n("ep-order").value=u.order||"desc",n("ep-limit").value=u.limit??50,n("ep-enabled").checked=u.enabled!==!1,await R(),te(u.fields||[]),ne(u.sort||"");for(const[e,t]of Object.entries(u.filter||{})){const{field:r,op:o}=ke(e);M(r,o,String(t))}g=u,B=JSON.stringify(I())}else await R(),M();oe(),Z(),G.destroy();for(const e of["ep-name","ep-path","ep-limit"])n(e).addEventListener("input",h);for(const e of["ep-mode","ep-order","ep-sort"])n(e).addEventListener("change",h);n("ep-enabled").addEventListener("change",h),k.addEventListener("change",async()=>{z(),await R(),h()}),L.addEventListener("change",h),y.addEventListener("change",async()=>{await R(),h()}),n("ep-add-filter").addEventListener("click",()=>{M(),h()}),n("tryit-send").addEventListener("click",Q),n("tryit-history-clear").addEventListener("click",()=>{S.set(W,[]),Y()}),n("tryit-json-toggle").addEventListener("click",()=>{le(n("tryit-json").style.display==="none")}),n("tryit-body-copy").addEventListener("click",async()=>{if(!V){E.toast("Send a request first.",{type:"info"});return}try{await navigator.clipboard.writeText(V),E.toast("Response copied.",{type:"success"})}catch{E.toast("Copy failed.",{type:"error"})}}),n("tryit-copy-curl").addEventListener("click",async()=>{if(!J){E.toast("Send a request first.",{type:"info"});return}try{await navigator.clipboard.writeText(J),E.toast("curl command copied.",{type:"success"})}catch{E.toast("Copy failed.",{type:"error"})}});async function de(){const e=I();if(!e.name){E.toast("A name is required.",{type:"error"});return}if(!e.path.startsWith("/")){E.toast('The path must start with "/".',{type:"error"});return}try{if(q)g=await _.apiEndpoints.update(q,e),B=JSON.stringify(I()),E.toast("Endpoint saved.",{type:"success"}),Z();else{const t=await _.apiEndpoints.create(e);E.toast("Endpoint created.",{type:"success"}),location.hash="#/api-endpoints/edit/"+encodeURIComponent(t.id)}}catch(t){E.toast(`Save failed: ${t.message||t}`,{type:"error"})}}n("ep-save").addEventListener("click",de);function H(e){if(!document.getElementById("ep-save")){document.removeEventListener("keydown",H),O===H&&(O=null);return}if(!(e.metaKey||e.ctrlKey))return;const r=e.key.toLowerCase();r==="s"?(e.preventDefault(),de()):r==="enter"&&(e.preventDefault(),g&&!D()?Q():D()&&E.toast("Save first \u2014 Send tests the saved definition.",{type:"info"}))}O&&document.removeEventListener("keydown",O),O=H,document.addEventListener("keydown",H),Y(),Domma.icons.scan(v)}};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import{api as
|
|
1
|
+
import{api as d}from"../api.js";import{filterByProject as p,getProjectFromHash as c}from"../lib/project-context.js";function n(a){return String(a??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function r(a){return a==="public"?'<span class="badge badge-warning">Public</span>':a==="token"?'<span class="badge badge-info">Token</span>':`<span class="badge badge-secondary">${n(a)}</span>`}export const apiEndpointsView={templateUrl:"/admin/js/templates/api-endpoints.html",async onMount(a){const l=E.loader(a.get(0),{type:"dots"});let i=await d.apiEndpoints.list().catch(()=>[]);l.destroy();const s=c();s&&(i=p(i,s)),T.create("#api-endpoints-table",{data:i,emptyMessage:'No endpoints yet. Click "New endpoint" to build one.',columns:[{key:"name",title:"Name",sortable:!0},{key:"path",title:"URL",render:(e,t)=>`<code>/api/x/${n(t.project)}${n(t.path)}</code>`},{key:"collection",title:"Collection",sortable:!0,render:e=>`<code>${n(e)}</code>`},{key:"mode",title:"Mode",render:e=>n(e)},{key:"auth",title:"Auth",render:e=>r(e)},{key:"enabled",title:"Status",render:e=>e?'<span class="badge badge-success">Enabled</span>':'<span class="badge badge-secondary">Disabled</span>'},{key:"_actions",title:"Actions",render:(e,t)=>`
|
|
2
2
|
<span style="display:inline-flex;gap:0.25rem;">
|
|
3
3
|
<a class="btn btn-sm btn-ghost" href="#/api-endpoints/edit/${encodeURIComponent(t.id)}" data-tooltip="Edit"><span data-icon="edit"></span></a>
|
|
4
4
|
<button class="btn btn-sm btn-ghost btn-toggle-endpoint" data-id="${n(t.id)}" data-enabled="${t.enabled?"1":""}" data-tooltip="${t.enabled?"Disable":"Enable"}"><span data-icon="${t.enabled?"pause":"play"}"></span></button>
|
|
5
5
|
<button class="btn btn-sm btn-danger btn-delete-endpoint" data-id="${n(t.id)}" data-name="${n(t.name)}" data-tooltip="Delete"><span data-icon="trash"></span></button>
|
|
6
6
|
</span>
|
|
7
|
-
`}]}),Domma.icons.scan(a.get(0)),document.querySelectorAll("#api-endpoints-table [data-tooltip]").forEach(e=>{E.tooltip(e,{content:e.getAttribute("data-tooltip"),position:"top"})}),a.off("click",".btn-toggle-endpoint").on("click",".btn-toggle-endpoint",async function(){const e=$(this).data("id"),t=!!$(this).data("enabled");try{await
|
|
7
|
+
`}]}),Domma.icons.scan(a.get(0)),document.querySelectorAll("#api-endpoints-table [data-tooltip]").forEach(e=>{E.tooltip(e,{content:e.getAttribute("data-tooltip"),position:"top"})}),a.off("click",".btn-toggle-endpoint").on("click",".btn-toggle-endpoint",async function(){const e=$(this).data("id"),t=!!$(this).data("enabled");try{await d.apiEndpoints.update(e,{enabled:!t}),E.toast(`Endpoint ${t?"disabled":"enabled"}.`,{type:"success"}),location.reload()}catch(o){E.toast(`Update failed: ${o.message||o}`,{type:"error"})}}),a.off("click",".btn-delete-endpoint").on("click",".btn-delete-endpoint",async function(){const e=$(this).data("id"),t=$(this).data("name");if(await E.confirm(`Delete endpoint "${t}"? External callers using it will immediately get 404s. This cannot be undone.`))try{await d.apiEndpoints.remove(e),E.toast("Endpoint deleted.",{type:"success"}),location.reload()}catch(o){E.toast(`Delete failed: ${o.message||o}`,{type:"error"})}})}};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{api as m}from"../api.js";function d(
|
|
2
|
-
`)){const n=
|
|
3
|
-
enquiries: create, read`,n.appendChild(b("Name",
|
|
1
|
+
import{api as m}from"../api.js";function d(a){return String(a??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function f(a){return!Array.isArray(a)||a.length===0?'<span class="text-muted">All collections in project</span>':d(a.map(l=>{const r=Array.isArray(l.verbs)&&l.verbs.length?l.verbs.join(","):"all";return`${l.collection}: ${r}`}).join("; "))}function g(a){const l=[];for(const r of(a||"").split(`
|
|
2
|
+
`)){const n=r.trim();if(!n)continue;const[o,e]=n.split(":").map(s=>s.trim());if(!o)return{error:`Invalid scope line: "${n}"`};const t={collection:o};if(e){const s=e.split(",").map(c=>c.trim()).filter(Boolean),i=s.find(c=>!["create","read","update","delete"].includes(c));if(i)return{error:`Unknown verb "${i}" in scope "${n}"`};t.verbs=s}l.push(t)}return{scopes:l}}function b(a,l,r){const n=document.createElement("div");n.style.marginBottom=".75rem";const o=document.createElement("label");if(o.className="form-label",o.textContent=a,n.appendChild(o),n.appendChild(l),r){const e=document.createElement("p");e.className="text-muted",e.style.cssText="font-size:.8rem;margin:.25rem 0 0;",e.textContent=r,n.appendChild(e)}return n}function h(a,l){const r=E.modal({title:"Token created",size:"sm"}),n=document.createElement("div");n.style.padding="1rem";const o=document.createElement("p");o.innerHTML="<strong>Copy this token now.</strong> It is shown once and cannot be recovered \u2014 only a hash is stored.",o.style.marginBottom=".75rem",n.appendChild(o);const e=document.createElement("code");e.textContent=a,e.style.cssText="display:block;padding:.6rem;word-break:break-all;user-select:all;margin-bottom:.75rem;",n.appendChild(e);const t=document.createElement("button");t.className="btn btn-primary",t.textContent="Copy to clipboard",t.style.marginRight=".5rem",t.addEventListener("click",async()=>{try{await navigator.clipboard.writeText(a),t.textContent="Copied!"}catch{E.toast("Copy failed \u2014 select the token text manually.",{type:"error"})}}),n.appendChild(t);const s=document.createElement("button");s.className="btn btn-secondary",s.textContent="Done",s.addEventListener("click",()=>{r.close(),l()}),n.appendChild(s),r.element.appendChild(n),r.open()}function v(a,l){const r=E.modal({title:"New API Token",size:"md"}),n=document.createElement("div");n.style.padding=".5rem 1rem 1rem";const o=document.createElement("input");o.type="text",o.className="form-input",o.placeholder="e.g. mobile-app, ci-pipeline";const e=document.createElement("select");e.className="form-input";for(const c of a){const p=document.createElement("option");p.value=c.slug,p.textContent=`${c.name} (${c.slug})`,e.appendChild(p)}const t=document.createElement("input");t.type="datetime-local",t.className="form-input";const s=document.createElement("textarea");s.className="form-input",s.rows=3,s.placeholder=`jobs: read
|
|
3
|
+
enquiries: create, read`,n.appendChild(b("Name",o)),n.appendChild(b("Project",e,"The token only works on collections in this project.")),n.appendChild(b("Expires (optional)",t,"Leave empty for a non-expiring token.")),n.appendChild(b("Scopes (optional)",s,'One per line: "collection: verb, verb". Leave empty to allow every collection in the project.'));const i=document.createElement("button");i.className="btn btn-primary",i.textContent="Create token",i.addEventListener("click",async()=>{const c=o.value.trim();if(!c){E.toast("A token name is required.",{type:"error"});return}const{scopes:p,error:y}=g(s.value);if(y){E.toast(y,{type:"error"});return}const k={name:c,project:e.value,scopes:p,expiresAt:t.value?new Date(t.value).toISOString():null};try{i.disabled=!0;const{plaintext:u}=await m.apiTokens.create(k);r.close(),h(u,l)}catch(u){i.disabled=!1,E.toast(`Create failed: ${u.message||u}`,{type:"error"})}}),n.appendChild(i),r.element.appendChild(n),r.open(),setTimeout(()=>o.focus(),100)}export const apiTokensView={templateUrl:"/admin/js/templates/api-tokens.html",async onMount(a){const l=E.loader(a.get(0),{type:"dots"}),[r,n]=await Promise.all([m.apiTokens.list().catch(()=>[]),m.projects.list().catch(()=>[])]);l.destroy(),T.create("#api-tokens-table",{data:r,emptyMessage:'No API tokens yet. Click "New token" to create one.',columns:[{key:"name",title:"Name",sortable:!0},{key:"project",title:"Project",sortable:!0,render:e=>`<code>${d(e)}</code>`},{key:"tokenHint",title:"Token",render:e=>`<code>dcms_\u2026${d(e||"????")}</code>`},{key:"scopes",title:"Scopes",render:e=>f(e)},{key:"enabled",title:"Status",render:(e,t)=>t.expiresAt&&Date.parse(t.expiresAt)<Date.now()?'<span class="badge badge-warning">Expired</span>':e?'<span class="badge badge-success">Enabled</span>':'<span class="badge badge-secondary">Disabled</span>'},{key:"expiresAt",title:"Expires",render:e=>e?D(e).format("D MMM YYYY, HH:mm"):'<span class="text-muted">\u2014</span>'},{key:"lastUsedAt",title:"Last used",render:e=>e?D(e).format("D MMM YYYY, HH:mm"):'<span class="text-muted">Never</span>'},{key:"_actions",title:"Actions",render:(e,t)=>`
|
|
4
4
|
<span style="display:inline-flex;gap:0.25rem;">
|
|
5
5
|
<button class="btn btn-sm btn-ghost btn-toggle-token" data-id="${d(t.id)}" data-enabled="${t.enabled?"1":""}" data-tooltip="${t.enabled?"Disable":"Enable"}"><span data-icon="${t.enabled?"pause":"play"}"></span></button>
|
|
6
6
|
<button class="btn btn-sm btn-danger btn-revoke-token" data-id="${d(t.id)}" data-name="${d(t.name)}" data-tooltip="Revoke"><span data-icon="trash"></span></button>
|
|
7
7
|
</span>
|
|
8
|
-
`}]}),Domma.icons.scan(
|
|
8
|
+
`}]}),Domma.icons.scan(a.get(0)),document.querySelectorAll("#api-tokens-table [data-tooltip]").forEach(e=>{E.tooltip(e,{content:e.getAttribute("data-tooltip"),position:"top"})});const o=()=>location.reload();a.off("click","#btn-new-token").on("click","#btn-new-token",()=>{if(!n.length){E.toast("No projects available \u2014 create a project first.",{type:"error"});return}v(n,o)}),a.off("click",".btn-toggle-token").on("click",".btn-toggle-token",async function(){const e=$(this).data("id"),t=!!$(this).data("enabled");try{await m.apiTokens.update(e,{enabled:!t}),E.toast(`Token ${t?"disabled":"enabled"}.`,{type:"success"}),o()}catch(s){E.toast(`Update failed: ${s.message||s}`,{type:"error"})}}),a.off("click",".btn-revoke-token").on("click",".btn-revoke-token",async function(){const e=$(this).data("id"),t=$(this).data("name");if(await E.confirm(`Revoke token "${t}"? External callers using it will immediately lose access. This cannot be undone.`))try{await m.apiTokens.revoke(e),E.toast("Token revoked.",{type:"success"}),o()}catch(s){E.toast(`Revoke failed: ${s.message||s}`,{type:"error"})}})}};
|
package/admin/js/views/blocks.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{api as
|
|
2
|
-
<a href="#/blocks/edit/${
|
|
3
|
-
<button class="btn btn-sm btn-ghost js-export-block" data-name="${
|
|
4
|
-
<button class="btn btn-sm btn-danger js-delete-block" data-name="${
|
|
5
|
-
</div>`}}]}),
|
|
1
|
+
import{api as i}from"../api.js";import{filterByProject as m,getProjectFromHash as u}from"../lib/project-context.js";function d(e){return String(e??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function f(e){for(;e.firstChild;)e.removeChild(e.firstChild)}export const blocksView={templateUrl:"/admin/js/templates/blocks.html",async onMount(e){k(),await l(e),y(e),Domma.icons.scan(e.get(0))}};let p=!1;function k(){p||(p=!0,I.register("download",{viewBox:"0 0 24 24",paths:["M12 3v12","M7 10l5 5 5-5","M5 19h14"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("upload",{viewBox:"0 0 24 24",paths:["M12 21V9","M7 14l5-5 5 5","M5 5h14"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("plus",{viewBox:"0 0 24 24",paths:["M12 5v14","M5 12h14"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}))}async function l(e){const o=e.find("#blocks-table-container").get(0);if(!o)return;let r=[];const n=E.loader(e.get(0),{type:"dots"});try{r=await i.blocks.list()}catch(t){f(o);const s=document.createElement("p");s.className="text-muted",s.textContent=`Failed to load blocks: ${t.message}`,o.appendChild(s);return}finally{n.destroy()}const a=u();a&&(r=m(r,a)),T.create(o,{data:r,emptyMessage:'No blocks yet. Click "New Block" to create your first template.',columns:[{key:"name",title:"Name",render:t=>`<a href="#/blocks/edit/${d(t)}">${d(t)}.html</a>`},{key:"size",title:"Size",render:t=>`${t} B`},{key:"updatedAt",title:"Updated",render:t=>t?new Date(t).toLocaleString():"\u2014"},{key:"name",title:"Actions",render:t=>{const s=d(t);return`<div style="display:flex;gap:.4rem;justify-content:flex-end;">
|
|
2
|
+
<a href="#/blocks/edit/${s}" class="btn btn-sm btn-ghost" data-tooltip="Edit"><span data-icon="edit"></span></a>
|
|
3
|
+
<button class="btn btn-sm btn-ghost js-export-block" data-name="${s}" data-tooltip="Export as .dmblock.json"><span data-icon="download"></span></button>
|
|
4
|
+
<button class="btn btn-sm btn-danger js-delete-block" data-name="${s}" data-tooltip="Delete"><span data-icon="trash"></span></button>
|
|
5
|
+
</div>`}}]}),o.querySelectorAll(".js-delete-block").forEach(t=>{t.addEventListener("click",async()=>{await b(t.dataset.name,e)})}),o.querySelectorAll(".js-export-block").forEach(t=>{t.addEventListener("click",async()=>{try{await i.blocks.exportBundle(t.dataset.name)}catch(s){E.toast(s.message||"Export failed.",{type:"error"})}})}),Domma.icons.scan(o),o.querySelectorAll("[data-tooltip]").forEach(t=>{E.tooltip(t,{content:t.getAttribute("data-tooltip"),position:"top"})})}async function b(e,o){if(await E.confirm(`Delete block "${e}"? This cannot be undone.`))try{await i.blocks.delete(e),E.toast("Block deleted.",{type:"success"}),await l(o)}catch(n){E.toast(n.message||"Failed to delete block.",{type:"error"})}}function y(e){const o=e.find("#import-block-btn").get(0),r=e.find("#import-block-file").get(0);!o||!r||(o.addEventListener("click",()=>r.click()),r.addEventListener("change",async()=>{const n=r.files?.[0];if(!n)return;r.value="";let a;try{const t=await n.text();a=JSON.parse(t)}catch{E.toast("Not a valid .dmblock.json file (could not parse JSON).",{type:"error"});return}if(!a||typeof a!="object"||!a.name||typeof a.html!="string"){E.toast("Bundle is missing a name or html field.",{type:"error"});return}try{const t=await i.blocks.importBundle(a);E.toast(`Imported "${t.name}".`,{type:"success"}),await l(e)}catch(t){if(t.code==="CONFLICT"){if(!await E.confirm(`A block named "${t.name}" already exists. Overwrite it with the imported version?`)){E.toast("Import cancelled.",{type:"info"});return}try{const c=await i.blocks.importBundle(a,{overwrite:!0});E.toast(`Overwrote "${c.name}".`,{type:"success"}),await l(e)}catch(c){E.toast(c.message||"Import failed.",{type:"error"})}return}E.toast(t.message||"Import failed.",{type:"error"})}}))}
|