domma-cms 1.8.36 → 1.8.38

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/js/app.js CHANGED
@@ -1,23 +1,49 @@
1
- import{installSmoothCarets as K}from"./lib/smooth-caret.js";import{views as J}from"./views/index.js";import{withPluginChrome as O}from"./lib/plugin-chrome.js";import{api as c,getUser as x,isAuthenticated as m,logout as Y,sendToLogin as Q}from"./api.js";import{claimDrafts as X}from"./lib/draft-owner.js";import{isAuthScreen as b,loginHashFor as Z}from"./lib/login-arrange.js";import{installHttpInterceptor as tt}from"./http-interceptor.js";import{installResizableSlideovers as et}from"./lib/slideover-resizable.js";import{installActivityThrobber as it}from"./lib/activity-throbber.js";import{installUpdateNotice as ot}from"./lib/update-notice.js";import{isPathAllowed as at,redirectFor as st}from"./lib/admin-scope.js";import{deliverDesktop as nt,desktopActive as rt,notificationSettings as lt}from"./lib/desktop-notify.js";import{avatarUrl as ct}from"./lib/avatar.js";import{installCalculator as mt}from"./lib/calculator.js";import{takeOverviewPass as pt,withDashboardStrip as _}from"./lib/dashboards-strip.js";import{installHotkeys as dt}from"./lib/hotkeys-ui.js";import{applyAdminBrand as V}from"./lib/admin-brand.js";import{installRouterCatchUp as ut}from"./lib/router-catch-up.js";import{installSidebarDrawer as ht}from"./lib/sidebar-drawer.js";$(()=>{K(document),tt(),mt(),ot(),it(),et(),ht(),(async()=>{const{applyAdminTheme:t,refreshAdminTheme:i}=await import("./lib/admin-theme.js");m()?await i(c,{init:!0}):t({dommaTheme:"charcoal-dark"},{init:!0})})();let p=null,h=null,l="/",w=!1,g=null;function D(t){if(P[t])return E.toast(`${P[t]} is switched off on this site.`,{type:"info"}),"/";if(t.split("?")[0]==="/my-dashboard")return"/dashboards";const i=y[t]||st(p,t);return i||((t.split("?")[0]||"/")==="/"&&l&&l!=="/"&&!pt()?y[l]||l:null)}const y={},P={};R.use(async(t,i,e)=>{if(b(t.path))return e();if(!m()){Q();return}const o=D(t.path);if(o){R.navigate(o);return}e()});async function f(){try{const t=await c.get("/auth/permissions");p=t.adminScope||null,h=t.adminBrand||null,V(h),l=t.adminHome||"/";const i=t.permissions||[];return w=at(p,"/settings")&&i.some(e=>e==="settings"||e.startsWith("settings.")),g=i.some(e=>e==="notifications"||e.startsWith("notifications.")),i}catch{return p=null,l="/",h||V(null),w=!1,g=null,[]}}document.addEventListener("dm:admin-home-changed",()=>{f()});let N=null,A=!1;document.addEventListener("dm:sidebar-rebuild",()=>{if(N){A=!0;return}N=(async()=>{do{A=!1;try{await j(await f())}catch{}}while(A)})().finally(()=>{N=null})});async function j(t){const{renderAdminSidebar:i}=await import("./lib/sidebar-renderer.js");await i({mount:"#admin-sidebar",permissions:t,adminScope:p,brand:h})}M.subscribe("router:afterChange",({to:t})=>{b(t.path)&&(u&&(clearInterval(u),u=null),p=null,l="/",w=!1,g=null)});const W=[{path:"/",view:"dashboard",title:"Dashboard - Domma CMS"},{path:"/dashboards",view:"dashboards",title:"Dashboards - Domma CMS"},{path:"/my-dashboard",view:"dashboards",title:"Dashboards - Domma CMS"},{path:"/pages",view:"pages",title:"Pages - Domma CMS"},{path:"/pages/new",view:"pageEditor",title:"New Page - Domma CMS"},{path:"/pages/edit/*",view:"pageEditor",title:"Edit Page - Domma CMS"},{path:"/media",view:"media",title:"Media - Domma CMS"},{path:"/menus",view:"menus",title:"Menus - Domma CMS"},{path:"/context-menus",view:"contextMenus",title:"Context Menus - Domma CMS"},{path:"/context-menus/new",view:"contextMenuEditor",title:"New Context Menu - Domma CMS"},{path:"/context-menus/edit/:slug",view:"contextMenuEditor",title:"Edit Context Menu - Domma CMS"},{path:"/menus/new",view:"menuEditor",title:"New Menu - Domma CMS"},{path:"/menus/edit/:slug",view:"menuEditor",title:"Edit Menu - Domma CMS"},{path:"/menu-locations",view:"menuLocations",title:"Menu Locations - Domma CMS"},{path:"/navigation",view:"menusRedirect",title:"Menus - Domma CMS"},{path:"/layouts",view:"layouts",title:"Layouts - Domma CMS"},{path:"/settings",view:"settings",title:"Settings - Domma CMS"},{path:"/theme",view:"theme",title:"Theme - Domma CMS"},{path:"/users",view:"users",title:"Users - Domma CMS"},{path:"/users/new",view:"userEditor",title:"New User - Domma CMS"},{path:"/users/edit/:id",view:"userEditor",title:"Edit User - Domma CMS"},{path:"/plugins",view:"plugins",title:"Plugins - Domma CMS"},{path:"/plugins/code/:name",view:"pluginCode",title:"Plugin Code - Domma CMS"},{path:"/documentation",view:"documentation",title:"Usage - Domma CMS"},{path:"/tutorials",view:"tutorials",title:"Tutorials - Domma CMS"},{path:"/tutorials/crud",view:"tutorialCrud",title:"Building a CRUD App - Domma CMS"},{path:"/tutorials/editor",view:"tutorialEditor",title:"The Editor - Domma CMS"},{path:"/tutorials/plugin",view:"tutorialPlugin",title:"Writing a Tool - Domma CMS"},{path:"/tutorials/forms",view:"tutorialForms",title:"Form Follow-Up - Domma CMS"},{path:"/docs/components",view:"componentsReference",title:"Components Reference - Domma CMS"},{path:"/docs/components-howto",view:"componentsHowto",title:"Components How-To - Domma CMS"},{path:"/docs/components-walkthrough",view:"componentsWalkthrough",title:"Components Walkthrough - Domma CMS"},{path:"/docs/components-rules",view:"componentsRules",title:"Components Rules - Domma CMS"},{path:"/docs/usage/pages",view:"usagePages",title:"Pages - Usage - Domma CMS"},{path:"/docs/usage/media",view:"usageMedia",title:"Media - Usage - Domma CMS"},{path:"/docs/usage/navigation",view:"usageNavigation",title:"Navigation - Usage - Domma CMS"},{path:"/docs/usage/dconfig",view:"usageDconfig",title:"DConfig - Usage - Domma CMS"},{path:"/docs/usage/shortcodes",view:"usageShortcodes",title:"Shortcodes - Usage - Domma CMS"},{path:"/docs/usage/site-settings",view:"usageSiteSettings",title:"Site Settings - Usage - Domma CMS"},{path:"/docs/usage/plugins",view:"usagePlugins",title:"Plugins - Usage - Domma CMS"},{path:"/docs/usage/users-roles",view:"usageUsersRoles",title:"Users & Roles - Usage - Domma CMS"},{path:"/docs/usage/views",view:"usageViews",title:"Views - Usage - Domma CMS"},{path:"/docs/usage/actions",view:"usageActions",title:"Actions - Usage - Domma CMS"},{path:"/docs/usage/cta-shortcode",view:"usageCtaShortcode",title:"CTA Shortcode - Usage - Domma CMS"},{path:"/docs/usage/editions",view:"usageEditions",title:"Editions & Licences - Usage - Domma CMS"},{path:"/docs/usage/collections",view:"usageCollections",title:"Collections & Forms - Usage - Domma CMS"},{path:"/docs/usage/blocks",view:"usageBlocks",title:"Blocks - Usage - Domma CMS"},{path:"/docs/usage/tools",view:"usageTools",title:"Built-in Tools - Usage - Domma CMS"},{path:"/docs/usage/dashboard",view:"usageDashboard",title:"Dashboard - Usage - Domma CMS"},{path:"/docs/usage/search-engines",view:"usageSearchEngines",title:"Search Engines & AI - Usage - Domma CMS"},{path:"/docs/plugins",view:"pluginGuides",title:"Plugin Guides - Domma CMS"},{path:"/docs/plugins/*",view:"pluginGuide",title:"Plugin Guide - Domma CMS"},{path:"/docs/api/authentication",view:"apiRefAuthentication",title:"Authentication - API - Domma CMS"},{path:"/docs/api/pages",view:"apiRefPages",title:"Pages - API - Domma CMS"},{path:"/docs/api/settings",view:"apiRefSettings",title:"Settings - API - Domma CMS"},{path:"/docs/api/layouts",view:"apiRefLayouts",title:"Layouts - API - Domma CMS"},{path:"/docs/api/navigation",view:"apiRefNavigation",title:"Navigation - API - Domma CMS"},{path:"/docs/api/media",view:"apiRefMedia",title:"Media - API - Domma CMS"},{path:"/docs/api/users",view:"apiRefUsers",title:"Users - API - Domma CMS"},{path:"/docs/api/plugins",view:"apiRefPlugins",title:"Plugins - API - Domma CMS"},{path:"/docs/api/collections",view:"apiRefCollections",title:"Collections - API - Domma CMS"},{path:"/docs/api/views",view:"apiRefViews",title:"Views API - Domma CMS"},{path:"/docs/api/actions",view:"apiRefActions",title:"Actions API - Domma CMS"},{path:"/docs/api/forms",view:"apiRefForms",title:"Forms API - Domma CMS"},{path:"/docs/api/scaffold",view:"apiRefScaffold",title:"Scaffold API - Domma CMS"},{path:"/docs/api/external",view:"apiRefExternal",title:"External API & Tokens - Domma CMS"},{path:"/docs/api/content",view:"apiRefContent",title:"Content API - Domma CMS"},{path:"/docs/api/builder",view:"apiRefBuilder",title:"API Builder - Domma CMS"},{path:"/api-reference",view:"apiReference",title:"API Reference - Domma CMS"},{path:"/collections",view:"collections",title:"Collections - Domma CMS"},{path:"/collections/new",view:"collectionEditor",title:"New Collection - Domma CMS"},{path:"/collections/edit/:slug",view:"collectionEditor",title:"Edit Collection - Domma CMS"},{path:"/collections/:slug/entries",view:"collectionEntries",title:"Entries - Domma CMS"},{path:"/forms",view:"forms",title:"Forms - Domma CMS"},{path:"/forms/new",view:"formEditor",title:"New Form - Domma CMS"},{path:"/forms/edit/:slug",view:"formEditor",title:"Edit Form - Domma CMS"},{path:"/forms/:slug/submissions",view:"formSubmissions",title:"Submissions - Domma CMS"},{path:"/views",view:"viewsList",title:"Views - Domma CMS"},{path:"/views/new",view:"viewEditor",title:"New View - Domma CMS"},{path:"/views/edit/:slug",view:"viewEditor",title:"Edit View - Domma CMS"},{path:"/views/:slug/preview",view:"viewPreview",title:"View Preview - Domma CMS"},{path:"/actions",view:"actionsList",title:"Actions - Domma CMS"},{path:"/actions/new",view:"actionEditor",title:"New Action - Domma CMS"},{path:"/actions/edit/:slug",view:"actionEditor",title:"Edit Action - Domma CMS"},{path:"/pro/docs",view:"proDocs",title:"Pro Documentation - Domma CMS"},{path:"/blocks",view:"blocks",title:"Blocks - Domma CMS"},{path:"/blocks/new",view:"pageEditor",title:"New Block - Domma CMS"},{path:"/blocks/edit/:name",view:"pageEditor",title:"Edit Block - Domma CMS"},{path:"/components",view:"components",title:"Components - Domma CMS"},{path:"/components/new",view:"pageEditor",title:"New Component - Domma CMS"},{path:"/components/edit/:name",view:"pageEditor",title:"Edit Component - Domma CMS"},{path:"/my-profile",view:"myProfile",title:"My Profile - Domma CMS"},{path:"/roles",view:"roles",title:"Roles & Permissions - Domma CMS"},{path:"/roles/edit/:id",view:"roleEditor",title:"Edit Role - Domma CMS"},{path:"/effects",view:"effects",title:"Effects - Domma CMS"},{path:"/search",view:"search",title:"Search - Domma CMS"},{path:"/content-api",view:"contentApi",title:"Content API - Domma CMS"},{path:"/notes",view:"notes",title:"Notes - Domma CMS"},{path:"/todo",view:"todo",title:"Todo - Domma CMS"},{path:"/calculator",view:"calculator",title:"Calculator - Domma CMS"},{path:"/analytics",view:"analytics",title:"Analytics - Domma CMS"},{path:"/seo",view:"seo",title:"SEO - Domma CMS"},{path:"/seo/:tab",view:"seo",title:"SEO - Domma CMS"},{path:"/wordpress-import",view:"wordpressImport",title:"Import from WordPress - Domma CMS"},{path:"/contacts",view:"contacts",title:"Contacts - Domma CMS"},{path:"/calls/new",view:"callNew",title:"Call now - Domma CMS"},{path:"/system/notifications",view:"notifications",title:"Notifications - Domma CMS"},{path:"/api-tokens",view:"apiTokens",title:"API Tokens - Domma CMS"},{path:"/api-endpoints",view:"apiEndpoints",title:"API Builder - Domma CMS"},{path:"/api-endpoints/new",view:"apiEndpointEditor",title:"New API Endpoint - Domma CMS"},{path:"/api-endpoints/edit/:id",view:"apiEndpointEditor",title:"Edit API Endpoint - Domma CMS"},{path:"/projects",view:"projects",title:"Projects - Domma CMS"},{path:"/projects/new",view:"projects",title:"New Project - Domma CMS"},{path:"/projects/edit/:slug",view:"projects",title:"Edit Project - Domma CMS"},{path:"/projects/:slug/settings",view:"projectSettings",title:"Project settings - Domma CMS"},{path:"/projects/:slug/pages",view:"pages",title:"Project pages - Domma CMS"},{path:"/projects/:slug/collections",view:"collections",title:"Project collections - Domma CMS"},{path:"/projects/:slug/forms",view:"forms",title:"Project forms - Domma CMS"},{path:"/projects/:slug/actions",view:"actionsList",title:"Project actions - Domma CMS"},{path:"/projects/:slug/menus",view:"menus",title:"Project menus - Domma CMS"},{path:"/projects/:slug/blocks",view:"blocks",title:"Project blocks - Domma CMS"},{path:"/projects/:slug/components",view:"components",title:"Project components - Domma CMS"},{path:"/projects/:slug/views",view:"viewsList",title:"Project views - Domma CMS"},{path:"/projects/:slug/roles",view:"roles",title:"Project roles - Domma CMS"},{path:"/projects/:slug/users",view:"users",title:"Project users - Domma CMS"},{path:"/projects/:slug/apis",view:"apiEndpoints",title:"Project APIs - Domma CMS"},{path:"/projects/:slug",view:"projectDetail",title:"Project - Domma CMS"},{path:"/login",view:"login",title:"Sign in - Domma CMS",onEnter:()=>{$("#admin-sidebar").hide(),$("#admin-topbar").hide()}},{path:"/reset-password",view:"login",title:"Reset Password - Domma CMS",onEnter:()=>{$("#admin-sidebar").hide(),$("#admin-topbar").hide()}}];M.subscribe("router:afterChange",async({to:t,from:i})=>{if(!b(t.path)){if($("#admin-sidebar").show(),$("#admin-topbar").show(),b(i?.path)){$("#topbar-user-name").remove(),import("./lib/admin-theme.js").then(a=>a.refreshAdminTheme(c)),await U();const e=await f(),o=D(t.path);if(o&&R.navigate(o),j(e),lt.read().signInToasts)try{const a=await c.system.notifications.list().catch(()=>[]),n=(Array.isArray(a)?a:[]).filter(s=>s.unread&&["warning","critical"].includes(s.data?.severity)).slice(0,3);for(const s of n){const v=d(s.data?.title||""),T=d((s.data?.body||"").slice(0,120));E.toast(`${v} - ${T}`,{type:s.data?.severity==="critical"?"error":"warning",duration:0})}}catch{}}B()}}),M.subscribe("router:afterChange",()=>{setTimeout(()=>{$(".btn-primary, .btn-danger").length&&Domma.effects.reveal(".btn-primary, .btn-danger",{animation:"fade",stagger:40,duration:300})},50)});const H=["#field-project","#menu-project","#collection-project","#endpoint-project","#action-project","#view-project","#block-project","#component-project","#role-project",'[name="project"]','[name="ownedByProject"]'];function q(t){return/^\/(pages|menus|context-menus|collections|forms|actions|views|blocks|components|users|roles|api-endpoints)\/(new|edit\/)/.test(t)}M.subscribe("router:afterChange",({to:t})=>{const i=t?String(t.path).split("?")[0]:"";if(!t||!q(i))return;const o=new URLSearchParams(location.hash.split("?")[1]||"").get("project");if(!o||!/\/new$/.test(i))return;let a=0;const n=60,s=1500,v=()=>{a+=n;for(const T of H){const C=document.querySelector(T);if(!C)continue;if(Array.from(C.options||[]).find(z=>z.value===o)){C.value=o,C.dispatchEvent(new Event("change",{bubbles:!0}));return}}a<s&&setTimeout(v,n)};setTimeout(v,n)});const L="cms_card_states",k=S.get(L)||{};M.subscribe("router:afterChange",()=>{setTimeout(()=>{$("#view-container .card-collapsible").each(function(){const t=$(this).find(".card-header h2, .card-header h3").first().text().trim();t&&k[t]==="collapsed"&&$(this).addClass("card-collapsed")})},200)}),$("#view-container").on("click",".card-collapsible .card-header",function(t){if($(t.target).closest("button, a").length)return;const i=$(this).closest(".card");i.toggleClass("card-collapsed");const e=$(this).find("h2, h3").first().text().trim();e&&(k[e]=i.hasClass("card-collapsed")?"collapsed":"open",S.set(L,k))}),dt(),document.addEventListener("keydown",t=>{if(!(t.ctrlKey||t.metaKey)||t.key!=="s"||window.location.hash.startsWith("#/login")||window.location.hash.startsWith("#/reset-password"))return;const i=document.querySelector("#view-container .view-header button.btn-primary");i&&(t.preventDefault(),i.click())});const r={...J},G={notes:{displayName:"Notes",icon:"edit-3"},todo:{displayName:"Todo",icon:"check-square"},calculator:{displayName:"Calculator",icon:"calculator"},analytics:{displayName:"Analytics",icon:"chart-bar"},seo:{displayName:"SEO",icon:"search"},wordpressImport:{displayName:"Import from WordPress",icon:"download"},contacts:{displayName:"Contacts",icon:"users"},projects:{displayName:"Projects",icon:"folder"},pages:{displayName:"Pages",icon:"file-text"},media:{displayName:"Media",icon:"image"},menus:{displayName:"Site menus",icon:"menu"},contextMenus:{displayName:"Context Menus",icon:"menu"},theme:{displayName:"Theme",icon:"droplet"},collections:{displayName:"Collections",icon:"database"},forms:{displayName:"Forms",icon:"layout"},viewsList:{displayName:"Views",icon:"eye"},actionsList:{displayName:"Actions",icon:"zap"},apiEndpoints:{displayName:"API Builder",icon:"code"},blocks:{displayName:"Blocks",icon:"box"},components:{displayName:"Components",icon:"component"},notifications:{displayName:"Notifications",icon:"bell"},roles:{displayName:"Roles",icon:"shield"},users:{displayName:"Users",icon:"users"},settings:{displayName:"Site Settings",icon:"settings"},effects:{displayName:"Effects",icon:"sparkles"},layouts:{displayName:"Layouts",icon:"layout"},plugins:{displayName:"Marketplace",icon:"store"},myProfile:{displayName:"My Profile",icon:"user"},apiTokens:{displayName:"API Tokens",icon:"key"},search:{displayName:"Search",icon:"search"},contentApi:{displayName:"Content API",icon:"file-text"},dashboard:{displayName:"Dashboard",icon:"home"},dashboards:{displayName:"Dashboards",icon:"home"},pageEditor:{displayName:"Pages",section:"Edit",icon:"file-text"},menuEditor:{displayName:"Site menus",section:"Edit",icon:"menu"},menuLocations:{displayName:"Site menus",section:"Locations",icon:"map-pin"},contextMenuEditor:{displayName:"Context Menus",section:"Edit",icon:"menu"},collectionEditor:{displayName:"Collections",section:"Edit",icon:"database"},collectionEntries:{displayName:"Collections",section:"Entries",icon:"database"},formEditor:{displayName:"Forms",section:"Edit",icon:"layout"},formSubmissions:{displayName:"Forms",section:"Submissions",icon:"inbox"},viewEditor:{displayName:"Views",section:"Edit",icon:"eye"},viewPreview:{displayName:"Views",section:"Preview",icon:"eye"},actionEditor:{displayName:"Actions",section:"Edit",icon:"zap"},apiEndpointEditor:{displayName:"API Builder",section:"Edit",icon:"code"},roleEditor:{displayName:"Roles",section:"Edit",icon:"shield"},userEditor:{displayName:"Users",section:"Edit",icon:"users"},projectDetail:{displayName:"Projects",section:"Overview",icon:"folder"},projectSettings:{displayName:"Projects",section:"Settings",icon:"folder"},pluginCode:{displayName:"Marketplace",section:"Code",icon:"code"}};for(const[t,i]of Object.entries(G))r[t]&&(r[t]=O(r[t],{plugin:t,licence:"Built in",...i}));r.dashboard=_(r.dashboard);const I=[...W];async function U(){if(m())try{const t=await c.plugins.adminConfig(),i=new Set(I.map(e=>e.path));for(const e of t.routes||[])i.has(e.path)||I.push(e);for(const[e,o]of Object.entries(t.views||{}))try{const a=await import(`/plugins/${o.entry}`);r[e]=O(a[o.exportName],(t.meta||{})[e])}catch{}r.dashboard=_(r.dashboard);for(const[e,{route:o}]of Object.entries(t.takeovers||{}))o&&(y[`/${e}`]=o);for(const[e,{enabled:o,displayName:a}]of Object.entries(t.tools||{}))o===!1&&(P[`/${e}`]=a);for(const{id:e,href:o}of t.css||[])if(!document.getElementById(e)){const a=document.createElement("link");a.id=e,a.rel="stylesheet",a.href=o,document.head.appendChild(a)}}catch{}}function B(){const t=x();if(!t||$("#topbar-user-name").length)return;const e={"super-admin":"Super Admin",admin:"Admin",user:"User"}[t.role]||t.role,o=ct(t);$("#topbar-user").html(`
2
- ${o?`<img id="topbar-avatar" class="topbar-avatar" src="${d(o)}" alt="">`:""}
3
- <span id="topbar-user-name" class="topbar-user-name">${d(t.name)}</span>
4
- <span class="topbar-role-badge topbar-role-badge--${d(t.role)}">${e}</span>
5
- `),$("#topbar-actions").get(0).innerHTML=`
1
+ import{installSmoothCarets as Y}from"./lib/smooth-caret.js";import{views as Q}from"./views/index.js";import{withPluginChrome as V}from"./lib/plugin-chrome.js";import{api as r,getUser as x,isAuthenticated as m,logout as X,sendToLogin as Z}from"./api.js";import{claimDrafts as tt}from"./lib/draft-owner.js";import{isAuthScreen as C,loginHashFor as et}from"./lib/login-arrange.js";import{installHttpInterceptor as it}from"./http-interceptor.js";import{installResizableSlideovers as at}from"./lib/slideover-resizable.js";import{installActivityThrobber as ot}from"./lib/activity-throbber.js";import{installUpdateNotice as st,renderCmsVersion as nt}from"./lib/update-notice.js";import{renderFrameworkVersions as _,wireAccountMenu as rt}from"./lib/topbar-account.js";import{refreshTopbarProject as L}from"./lib/topbar-project.js";import{isPathAllowed as lt,redirectFor as ct}from"./lib/admin-scope.js";import{deliverDesktop as mt,desktopActive as pt,notificationSettings as dt}from"./lib/desktop-notify.js";import{avatarUrl as ut,installAccountAvatar as ht}from"./lib/avatar.js";import{installCalculator as wt}from"./lib/calculator.js";import{takeOverviewPass as gt,withDashboardStrip as W}from"./lib/dashboards-strip.js";import{installHotkeys as ft}from"./lib/hotkeys-ui.js";import{applyAdminBrand as H}from"./lib/admin-brand.js";import{installRouterCatchUp as vt}from"./lib/router-catch-up.js";import{installSidebarDrawer as bt}from"./lib/sidebar-drawer.js";$(()=>{Y(document),it(),wt(),st(),ot(),at(),bt(),(async()=>{const{applyAdminTheme:t,refreshAdminTheme:i}=await import("./lib/admin-theme.js");m()?await i(r,{init:!0}):t({dommaTheme:"charcoal-dark"},{init:!0})})();let p=null,h=null,c="/",w=!1,g=null;function D(t){if(P[t])return E.toast(`${P[t]} is switched off on this site.`,{type:"info"}),"/";if(t.split("?")[0]==="/my-dashboard")return"/dashboards";const i=y[t]||ct(p,t);return i||((t.split("?")[0]||"/")==="/"&&c&&c!=="/"&&!gt()?y[c]||c:null)}const y={},P={};R.use(async(t,i,e)=>{if(C(t.path))return e();if(!m()){Z();return}const a=D(t.path);if(a){R.navigate(a);return}e()});async function f(){try{const t=await r.get("/auth/permissions");p=t.adminScope||null,h=t.adminBrand||null,H(h),c=t.adminHome||"/",_(t.versions);const i=t.permissions||[];return w=lt(p,"/settings")&&i.some(e=>e==="settings"||e.startsWith("settings.")),g=i.some(e=>e==="notifications"||e.startsWith("notifications.")),i}catch{return p=null,c="/",h||H(null),w=!1,g=null,[]}}document.addEventListener("dm:admin-home-changed",()=>{f()});let N=null,A=!1;document.addEventListener("dm:sidebar-rebuild",()=>{if(L(r),N){A=!0;return}N=(async()=>{do{A=!1;try{await j(await f())}catch{}}while(A)})().finally(()=>{N=null})});async function j(t){const{renderAdminSidebar:i}=await import("./lib/sidebar-renderer.js");await i({mount:"#admin-sidebar",permissions:t,adminScope:p,brand:h})}M.subscribe("router:afterChange",({to:t})=>{C(t.path)&&(u&&(clearInterval(u),u=null),p=null,c="/",w=!1,g=null)});const q=[{path:"/",view:"dashboard",title:"Dashboard - Domma CMS"},{path:"/dashboards",view:"dashboards",title:"Dashboards - Domma CMS"},{path:"/my-dashboard",view:"dashboards",title:"Dashboards - Domma CMS"},{path:"/pages",view:"pages",title:"Pages - Domma CMS"},{path:"/pages/new",view:"pageEditor",title:"New Page - Domma CMS"},{path:"/pages/edit/*",view:"pageEditor",title:"Edit Page - Domma CMS"},{path:"/media",view:"media",title:"Media - Domma CMS"},{path:"/menus",view:"menus",title:"Menus - Domma CMS"},{path:"/context-menus",view:"contextMenus",title:"Context Menus - Domma CMS"},{path:"/context-menus/new",view:"contextMenuEditor",title:"New Context Menu - Domma CMS"},{path:"/context-menus/edit/:slug",view:"contextMenuEditor",title:"Edit Context Menu - Domma CMS"},{path:"/menus/new",view:"menuEditor",title:"New Menu - Domma CMS"},{path:"/menus/edit/:slug",view:"menuEditor",title:"Edit Menu - Domma CMS"},{path:"/menu-locations",view:"menuLocations",title:"Menu Locations - Domma CMS"},{path:"/navigation",view:"menusRedirect",title:"Menus - Domma CMS"},{path:"/layouts",view:"layouts",title:"Layouts - Domma CMS"},{path:"/settings",view:"settings",title:"Settings - Domma CMS"},{path:"/theme",view:"theme",title:"Theme - Domma CMS"},{path:"/users",view:"users",title:"Users - Domma CMS"},{path:"/users/new",view:"userEditor",title:"New User - Domma CMS"},{path:"/users/edit/:id",view:"userEditor",title:"Edit User - Domma CMS"},{path:"/plugins",view:"plugins",title:"Plugins - Domma CMS"},{path:"/plugins/code/:name",view:"pluginCode",title:"Plugin Code - Domma CMS"},{path:"/documentation",view:"documentation",title:"Usage - Domma CMS"},{path:"/tutorials",view:"tutorials",title:"Tutorials - Domma CMS"},{path:"/tutorials/crud",view:"tutorialCrud",title:"Building a CRUD App - Domma CMS"},{path:"/tutorials/editor",view:"tutorialEditor",title:"The Editor - Domma CMS"},{path:"/tutorials/plugin",view:"tutorialPlugin",title:"Writing a Tool - Domma CMS"},{path:"/tutorials/forms",view:"tutorialForms",title:"Form Follow-Up - Domma CMS"},{path:"/docs/components",view:"componentsReference",title:"Components Reference - Domma CMS"},{path:"/docs/components-howto",view:"componentsHowto",title:"Components How-To - Domma CMS"},{path:"/docs/components-walkthrough",view:"componentsWalkthrough",title:"Components Walkthrough - Domma CMS"},{path:"/docs/components-rules",view:"componentsRules",title:"Components Rules - Domma CMS"},{path:"/docs/usage/pages",view:"usagePages",title:"Pages - Usage - Domma CMS"},{path:"/docs/usage/media",view:"usageMedia",title:"Media - Usage - Domma CMS"},{path:"/docs/usage/navigation",view:"usageNavigation",title:"Navigation - Usage - Domma CMS"},{path:"/docs/usage/dconfig",view:"usageDconfig",title:"DConfig - Usage - Domma CMS"},{path:"/docs/usage/shortcodes",view:"usageShortcodes",title:"Shortcodes - Usage - Domma CMS"},{path:"/docs/usage/site-settings",view:"usageSiteSettings",title:"Site Settings - Usage - Domma CMS"},{path:"/docs/usage/plugins",view:"usagePlugins",title:"Plugins - Usage - Domma CMS"},{path:"/docs/usage/users-roles",view:"usageUsersRoles",title:"Users & Roles - Usage - Domma CMS"},{path:"/docs/usage/views",view:"usageViews",title:"Views - Usage - Domma CMS"},{path:"/docs/usage/actions",view:"usageActions",title:"Actions - Usage - Domma CMS"},{path:"/docs/usage/cta-shortcode",view:"usageCtaShortcode",title:"CTA Shortcode - Usage - Domma CMS"},{path:"/docs/usage/editions",view:"usageEditions",title:"Editions & Licences - Usage - Domma CMS"},{path:"/docs/usage/collections",view:"usageCollections",title:"Collections & Forms - Usage - Domma CMS"},{path:"/docs/usage/blocks",view:"usageBlocks",title:"Blocks - Usage - Domma CMS"},{path:"/docs/usage/tools",view:"usageTools",title:"Built-in Tools - Usage - Domma CMS"},{path:"/docs/usage/dashboard",view:"usageDashboard",title:"Dashboard - Usage - Domma CMS"},{path:"/docs/usage/search-engines",view:"usageSearchEngines",title:"Search Engines & AI - Usage - Domma CMS"},{path:"/docs/plugins",view:"pluginGuides",title:"Plugin Guides - Domma CMS"},{path:"/docs/plugins/*",view:"pluginGuide",title:"Plugin Guide - Domma CMS"},{path:"/docs/api/authentication",view:"apiRefAuthentication",title:"Authentication - API - Domma CMS"},{path:"/docs/api/pages",view:"apiRefPages",title:"Pages - API - Domma CMS"},{path:"/docs/api/settings",view:"apiRefSettings",title:"Settings - API - Domma CMS"},{path:"/docs/api/layouts",view:"apiRefLayouts",title:"Layouts - API - Domma CMS"},{path:"/docs/api/navigation",view:"apiRefNavigation",title:"Navigation - API - Domma CMS"},{path:"/docs/api/media",view:"apiRefMedia",title:"Media - API - Domma CMS"},{path:"/docs/api/users",view:"apiRefUsers",title:"Users - API - Domma CMS"},{path:"/docs/api/plugins",view:"apiRefPlugins",title:"Plugins - API - Domma CMS"},{path:"/docs/api/collections",view:"apiRefCollections",title:"Collections - API - Domma CMS"},{path:"/docs/api/views",view:"apiRefViews",title:"Views API - Domma CMS"},{path:"/docs/api/actions",view:"apiRefActions",title:"Actions API - Domma CMS"},{path:"/docs/api/forms",view:"apiRefForms",title:"Forms API - Domma CMS"},{path:"/docs/api/scaffold",view:"apiRefScaffold",title:"Scaffold API - Domma CMS"},{path:"/docs/api/external",view:"apiRefExternal",title:"External API & Tokens - Domma CMS"},{path:"/docs/api/content",view:"apiRefContent",title:"Content API - Domma CMS"},{path:"/docs/api/builder",view:"apiRefBuilder",title:"API Builder - Domma CMS"},{path:"/api-reference",view:"apiReference",title:"API Reference - Domma CMS"},{path:"/collections",view:"collections",title:"Collections - Domma CMS"},{path:"/collections/new",view:"collectionEditor",title:"New Collection - Domma CMS"},{path:"/collections/edit/:slug",view:"collectionEditor",title:"Edit Collection - Domma CMS"},{path:"/collections/:slug/entries",view:"collectionEntries",title:"Entries - Domma CMS"},{path:"/forms",view:"forms",title:"Forms - Domma CMS"},{path:"/forms/new",view:"formEditor",title:"New Form - Domma CMS"},{path:"/forms/edit/:slug",view:"formEditor",title:"Edit Form - Domma CMS"},{path:"/forms/:slug/submissions",view:"formSubmissions",title:"Submissions - Domma CMS"},{path:"/views",view:"viewsList",title:"Views - Domma CMS"},{path:"/views/new",view:"viewEditor",title:"New View - Domma CMS"},{path:"/views/edit/:slug",view:"viewEditor",title:"Edit View - Domma CMS"},{path:"/views/:slug/preview",view:"viewPreview",title:"View Preview - Domma CMS"},{path:"/actions",view:"actionsList",title:"Actions - Domma CMS"},{path:"/actions/new",view:"actionEditor",title:"New Action - Domma CMS"},{path:"/actions/edit/:slug",view:"actionEditor",title:"Edit Action - Domma CMS"},{path:"/pro/docs",view:"proDocs",title:"Pro Documentation - Domma CMS"},{path:"/blocks",view:"blocks",title:"Blocks - Domma CMS"},{path:"/blocks/new",view:"pageEditor",title:"New Block - Domma CMS"},{path:"/blocks/edit/:name",view:"pageEditor",title:"Edit Block - Domma CMS"},{path:"/components",view:"components",title:"Components - Domma CMS"},{path:"/components/new",view:"pageEditor",title:"New Component - Domma CMS"},{path:"/components/edit/:name",view:"pageEditor",title:"Edit Component - Domma CMS"},{path:"/my-profile",view:"myProfile",title:"My Profile - Domma CMS"},{path:"/roles",view:"roles",title:"Roles & Permissions - Domma CMS"},{path:"/roles/edit/:id",view:"roleEditor",title:"Edit Role - Domma CMS"},{path:"/effects",view:"effects",title:"Effects - Domma CMS"},{path:"/search",view:"search",title:"Search - Domma CMS"},{path:"/content-api",view:"contentApi",title:"Content API - Domma CMS"},{path:"/notes",view:"notes",title:"Notes - Domma CMS"},{path:"/todo",view:"todo",title:"Todo - Domma CMS"},{path:"/calculator",view:"calculator",title:"Calculator - Domma CMS"},{path:"/analytics",view:"analytics",title:"Analytics - Domma CMS"},{path:"/seo",view:"seo",title:"SEO - Domma CMS"},{path:"/seo/:tab",view:"seo",title:"SEO - Domma CMS"},{path:"/wordpress-import",view:"wordpressImport",title:"Import from WordPress - Domma CMS"},{path:"/contacts",view:"contacts",title:"Contacts - Domma CMS"},{path:"/calls/new",view:"callNew",title:"Call now - Domma CMS"},{path:"/system/notifications",view:"notifications",title:"Notifications - Domma CMS"},{path:"/api-tokens",view:"apiTokens",title:"API Tokens - Domma CMS"},{path:"/api-endpoints",view:"apiEndpoints",title:"API Builder - Domma CMS"},{path:"/api-endpoints/new",view:"apiEndpointEditor",title:"New API Endpoint - Domma CMS"},{path:"/api-endpoints/edit/:id",view:"apiEndpointEditor",title:"Edit API Endpoint - Domma CMS"},{path:"/projects",view:"projects",title:"Projects - Domma CMS"},{path:"/projects/new",view:"projects",title:"New Project - Domma CMS"},{path:"/projects/edit/:slug",view:"projects",title:"Edit Project - Domma CMS"},{path:"/projects/:slug/settings",view:"projectSettings",title:"Project settings - Domma CMS"},{path:"/projects/:slug/pages",view:"pages",title:"Project pages - Domma CMS"},{path:"/projects/:slug/collections",view:"collections",title:"Project collections - Domma CMS"},{path:"/projects/:slug/forms",view:"forms",title:"Project forms - Domma CMS"},{path:"/projects/:slug/actions",view:"actionsList",title:"Project actions - Domma CMS"},{path:"/projects/:slug/menus",view:"menus",title:"Project menus - Domma CMS"},{path:"/projects/:slug/blocks",view:"blocks",title:"Project blocks - Domma CMS"},{path:"/projects/:slug/components",view:"components",title:"Project components - Domma CMS"},{path:"/projects/:slug/views",view:"viewsList",title:"Project views - Domma CMS"},{path:"/projects/:slug/roles",view:"roles",title:"Project roles - Domma CMS"},{path:"/projects/:slug/users",view:"users",title:"Project users - Domma CMS"},{path:"/projects/:slug/apis",view:"apiEndpoints",title:"Project APIs - Domma CMS"},{path:"/projects/:slug",view:"projectDetail",title:"Project - Domma CMS"},{path:"/login",view:"login",title:"Sign in - Domma CMS",onEnter:()=>{$("#admin-sidebar").hide(),$("#admin-topbar").hide()}},{path:"/reset-password",view:"login",title:"Reset Password - Domma CMS",onEnter:()=>{$("#admin-sidebar").hide(),$("#admin-topbar").hide()}}];M.subscribe("router:afterChange",async({to:t,from:i})=>{if(!C(t.path)){if($("#admin-sidebar").show(),$("#admin-topbar").show(),C(i?.path)){$("#topbar-user-name").remove(),import("./lib/admin-theme.js").then(o=>o.refreshAdminTheme(r)),await T();const e=await f(),a=D(t.path);if(a&&R.navigate(a),j(e),dt.read().signInToasts)try{const o=await r.system.notifications.list().catch(()=>[]),n=(Array.isArray(o)?o:[]).filter(s=>s.unread&&["warning","critical"].includes(s.data?.severity)).slice(0,3);for(const s of n){const v=d(s.data?.title||""),U=d((s.data?.body||"").slice(0,120));E.toast(`${v} - ${U}`,{type:s.data?.severity==="critical"?"error":"warning",duration:0})}}catch{}}F()}}),M.subscribe("router:afterChange",()=>{setTimeout(()=>{$(".btn-primary, .btn-danger").length&&Domma.effects.reveal(".btn-primary, .btn-danger",{animation:"fade",stagger:40,duration:300})},50)});const G=["#field-project","#menu-project","#collection-project","#endpoint-project","#action-project","#view-project","#block-project","#component-project","#role-project",'[name="project"]','[name="ownedByProject"]'];function z(t){return/^\/(pages|menus|context-menus|collections|forms|actions|views|blocks|components|users|roles|api-endpoints)\/(new|edit\/)/.test(t)}M.subscribe("router:afterChange",({to:t})=>{const i=t?String(t.path).split("?")[0]:"";if(!t||!z(i))return;const a=new URLSearchParams(location.hash.split("?")[1]||"").get("project");if(!a||!/\/new$/.test(i))return;let o=0;const n=60,s=1500,v=()=>{o+=n;for(const U of G){const b=document.querySelector(U);if(!b)continue;if(Array.from(b.options||[]).find(J=>J.value===a)){b.value=a,b.dispatchEvent(new Event("change",{bubbles:!0}));return}}o<s&&setTimeout(v,n)};setTimeout(v,n)});const B="cms_card_states",k=S.get(B)||{};M.subscribe("router:afterChange",()=>{setTimeout(()=>{$("#view-container .card-collapsible").each(function(){const t=$(this).find(".card-header h2, .card-header h3").first().text().trim();t&&k[t]==="collapsed"&&$(this).addClass("card-collapsed")})},200)}),$("#view-container").on("click",".card-collapsible .card-header",function(t){if($(t.target).closest("button, a").length)return;const i=$(this).closest(".card");i.toggleClass("card-collapsed");const e=$(this).find("h2, h3").first().text().trim();e&&(k[e]=i.hasClass("card-collapsed")?"collapsed":"open",S.set(B,k))}),ft(),document.addEventListener("keydown",t=>{if(!(t.ctrlKey||t.metaKey)||t.key!=="s"||window.location.hash.startsWith("#/login")||window.location.hash.startsWith("#/reset-password"))return;const i=document.querySelector("#view-container .view-header button.btn-primary");i&&(t.preventDefault(),i.click())});const l={...Q},K={notes:{displayName:"Notes",icon:"edit-3"},todo:{displayName:"Todo",icon:"check-square"},calculator:{displayName:"Calculator",icon:"calculator"},analytics:{displayName:"Analytics",icon:"chart-bar"},seo:{displayName:"SEO",icon:"search"},wordpressImport:{displayName:"Import from WordPress",icon:"download"},contacts:{displayName:"Contacts",icon:"users"},projects:{displayName:"Projects",icon:"folder"},pages:{displayName:"Pages",icon:"file-text"},media:{displayName:"Media",icon:"image"},menus:{displayName:"Site menus",icon:"menu"},contextMenus:{displayName:"Context Menus",icon:"menu"},theme:{displayName:"Theme",icon:"droplet"},collections:{displayName:"Collections",icon:"database"},forms:{displayName:"Forms",icon:"layout"},viewsList:{displayName:"Views",icon:"eye"},actionsList:{displayName:"Actions",icon:"zap"},apiEndpoints:{displayName:"API Builder",icon:"code"},blocks:{displayName:"Blocks",icon:"box"},components:{displayName:"Components",icon:"component"},notifications:{displayName:"Notifications",icon:"bell"},roles:{displayName:"Roles",icon:"shield"},users:{displayName:"Users",icon:"users"},settings:{displayName:"Site Settings",icon:"settings"},effects:{displayName:"Effects",icon:"sparkles"},layouts:{displayName:"Layouts",icon:"layout"},plugins:{displayName:"Marketplace",icon:"store"},myProfile:{displayName:"My Profile",icon:"user"},apiTokens:{displayName:"API Tokens",icon:"key"},search:{displayName:"Search",icon:"search"},contentApi:{displayName:"Content API",icon:"file-text"},dashboard:{displayName:"Dashboard",icon:"home"},dashboards:{displayName:"Dashboards",icon:"home"},pageEditor:{displayName:"Pages",section:"Edit",icon:"file-text"},menuEditor:{displayName:"Site menus",section:"Edit",icon:"menu"},menuLocations:{displayName:"Site menus",section:"Locations",icon:"map-pin"},contextMenuEditor:{displayName:"Context Menus",section:"Edit",icon:"menu"},collectionEditor:{displayName:"Collections",section:"Edit",icon:"database"},collectionEntries:{displayName:"Collections",section:"Entries",icon:"database"},formEditor:{displayName:"Forms",section:"Edit",icon:"layout"},formSubmissions:{displayName:"Forms",section:"Submissions",icon:"inbox"},viewEditor:{displayName:"Views",section:"Edit",icon:"eye"},viewPreview:{displayName:"Views",section:"Preview",icon:"eye"},actionEditor:{displayName:"Actions",section:"Edit",icon:"zap"},apiEndpointEditor:{displayName:"API Builder",section:"Edit",icon:"code"},roleEditor:{displayName:"Roles",section:"Edit",icon:"shield"},userEditor:{displayName:"Users",section:"Edit",icon:"users"},projectDetail:{displayName:"Projects",section:"Overview",icon:"folder"},projectSettings:{displayName:"Projects",section:"Settings",icon:"folder"},pluginCode:{displayName:"Marketplace",section:"Code",icon:"code"}};for(const[t,i]of Object.entries(K))l[t]&&(l[t]=V(l[t],{plugin:t,licence:"Built in",...i}));l.dashboard=W(l.dashboard);const I=[...q];async function T(){if(m())try{const t=await r.plugins.adminConfig(),i=new Set(I.map(e=>e.path));for(const e of t.routes||[])i.has(e.path)||I.push(e);for(const[e,a]of Object.entries(t.views||{}))try{const o=await import(`/plugins/${a.entry}`);l[e]=V(o[a.exportName],(t.meta||{})[e])}catch{}l.dashboard=W(l.dashboard);for(const[e,{route:a}]of Object.entries(t.takeovers||{}))a&&(y[`/${e}`]=a);for(const[e,{enabled:a,displayName:o}]of Object.entries(t.tools||{}))a===!1&&(P[`/${e}`]=o);for(const{id:e,href:a}of t.css||[])if(!document.getElementById(e)){const o=document.createElement("link");o.id=e,o.rel="stylesheet",o.href=a,document.head.appendChild(o)}}catch{}}function F(){const t=x();if(!t)return;if($("#topbar-user-name").length){L(r);return}const e={"super-admin":"Super Admin",admin:"Admin",user:"User"}[t.role]||t.role,a=ut(t);$("#topbar-user").get(0).innerHTML=`
2
+ <a id="topbar-project" class="topbar-action-link topbar-project" hidden>
3
+ <span data-icon="folder"></span>
4
+ <span id="topbar-project-name" class="topbar-project-name"></span>
5
+ </a>
6
+ <div id="topbar-versions-menu" class="topbar-account">
7
+ <button type="button" class="topbar-action-link" aria-label="Versions and layout" aria-expanded="false" aria-controls="topbar-versions-panel">
8
+ <span data-icon="layers"></span><span class="topbar-action-label">Versions</span><span data-icon="chevron-down"></span>
9
+ </button>
10
+ <div id="topbar-versions-panel" class="topbar-account-menu topbar-versions-panel" hidden>
11
+ <div class="topbar-versions" aria-label="Domma versions">
12
+ <span class="topbar-version-item" hidden>Domma Reactive <span id="topbar-reactive-version" class="topbar-version-badge"></span></span>
13
+ <span class="topbar-version-item" hidden>Domma JS <span id="topbar-js-version" class="topbar-version-badge"></span></span>
14
+ <span class="topbar-version-item" hidden>Domma CMS <span id="topbar-cms-version" class="topbar-version-badge"></span></span>
15
+ </div>
16
+ <label class="topbar-sidebar-choice"><input type="checkbox" id="topbar-show-sidebar"> Show side admin menu</label>
17
+ </div>
18
+ </div>
19
+ `,$("#topbar-actions").get(0).innerHTML=`
6
20
  <a href="#/system/notifications" id="topbar-bell" class="topbar-action-link" data-tooltip="Notifications" data-tooltip-placement="bottom" hidden>
7
21
  <span data-icon="bell"></span>
8
22
  <span class="topbar-action-label">Notifications</span>
9
23
  <span id="topbar-bell-badge" class="topbar-bell-badge" hidden></span>
10
24
  </a>
25
+ <div id="topbar-account" class="topbar-account">
26
+ <button type="button" class="topbar-action-link" aria-label="Account menu" aria-expanded="false" aria-controls="topbar-account-menu">
27
+ <span id="topbar-account-avatar" class="topbar-account-avatar" aria-hidden="true"></span><span class="topbar-action-label">Account</span><span data-icon="chevron-down"></span>
28
+ </button>
29
+ <div id="topbar-account-menu" class="topbar-account-menu" hidden>
30
+ <div class="topbar-account-identity">
31
+ ${a?`<img id="topbar-avatar" class="topbar-avatar" src="${d(a)}" alt="">`:""}
32
+ <span id="topbar-user-name" class="topbar-user-name">${d(t.name)}</span>
33
+ <span class="topbar-role-badge topbar-role-badge--${d(t.role)}">${d(e)}</span>
34
+ </div>
11
35
  <a href="#/my-profile" class="topbar-action-link" data-tooltip="My Profile" data-tooltip-placement="bottom">
12
36
  <span data-icon="user"></span>
13
- <span class="topbar-action-label">My Profile</span>
37
+ <span>My Profile</span>
14
38
  </a>
15
39
  <a href="#/settings" id="topbar-settings" class="topbar-action-link" data-tooltip="Settings" data-tooltip-placement="bottom" hidden>
16
40
  <span data-icon="settings"></span>
17
- <span class="topbar-action-label">Settings</span>
41
+ <span>Settings</span>
18
42
  </a>
19
43
  <a href="#" id="topbar-logout-btn" class="topbar-action-link topbar-signout" data-tooltip="Sign out" data-tooltip-placement="bottom">
20
44
  <span data-icon="log-out"></span>
21
- <span class="topbar-action-label">Sign out</span>
45
+ <span>Sign out</span>
22
46
  </a>
23
- `;const a=$("#topbar-bell").get(0);a&&(a.hidden=!0);const n=$("#topbar-settings").get(0);n&&(n.hidden=!w),$("#topbar-logout-btn").on("click",s=>{s.preventDefault(),Y()}),Domma.icons.scan("#admin-topbar"),E.tooltip("#topbar-actions [data-tooltip]",{placement:"bottom"}),F(),u||(u=setInterval(F,6e4))}function d(t){return String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}let u=null;async function F(){if(!(!m()||g===!1))try{const{count:t}=await c.system.notifications.unreadCount();$("#topbar-bell").removeAttr("hidden");const i=$("#topbar-bell-badge");t>0?i.text(t>99?"99+":String(t)).removeAttr("hidden"):i.attr("hidden","").text(""),t>0&&rt()&&nt(await c.system.notifications.list().catch(()=>[]))}catch{}}(async()=>{if(!m()&&!window.location.hash.startsWith("#/reset-password"))window.location.hash.startsWith("#/login")||(window.location.hash=Z(window.location.hash));else if(X(x()?.id),await U(),x()){const a=await f(),n=(window.location.hash||"#/").slice(1)||"/",s=D(n);s&&(window.location.hash=`#${s}`),await j(a),B()}const t=R._extractParams.bind(R);R._extractParams=function(o,a){const n=a.indexOf("?");if(n!==-1&&(a=a.slice(0,n)),o.endsWith("/*")){const s=o.slice(0,-2);return a.startsWith(s+"/")?{}:null}return t(o,a)};const i=R._renderNotFound.bind(R);let e="";R._renderNotFound=async function(o){return m()&&e!==o&&(e=o,await U(),R._matchRoute(o).route)?(e="",R._handleRouteChange()):(e="",m()&&$("#admin-sidebar").get(0)?.style.display==="none"?(E.toast("That link goes nowhere - here is your home page.",{type:"warning"}),R.navigate("/")):i(o))},ut(R),R.init({container:"#view-container",routes:I,views:r,default:"/",transitions:{enter:"fadeIn",leave:"fadeOut",duration:150}})})()});
47
+ </div>
48
+ </div>
49
+ `;const o=$("#topbar-bell").get(0);o&&(o.hidden=!0);const n=$("#topbar-settings").get(0);n&&(n.hidden=!w),$("#topbar-logout-btn").on("click",s=>{s.preventDefault(),X()}),Domma.icons.scan("#admin-topbar"),E.tooltip("#topbar-actions [data-tooltip]",{placement:"bottom"}),rt(t),ht(t),_(),nt(),L(r),O(),u||(u=setInterval(O,6e4))}function d(t){return String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}let u=null;async function O(){if(!(!m()||g===!1))try{const{count:t}=await r.system.notifications.unreadCount();$("#topbar-bell").removeAttr("hidden");const i=$("#topbar-bell-badge");t>0?i.text(t>99?"99+":String(t)).removeAttr("hidden"):i.attr("hidden","").text(""),t>0&&pt()&&mt(await r.system.notifications.list().catch(()=>[]))}catch{}}(async()=>{if(!m()&&!window.location.hash.startsWith("#/reset-password"))window.location.hash.startsWith("#/login")||(window.location.hash=et(window.location.hash));else if(tt(x()?.id),await T(),x()){const o=await f(),n=(window.location.hash||"#/").slice(1)||"/",s=D(n);s&&(window.location.hash=`#${s}`),await j(o),F()}const t=R._extractParams.bind(R);R._extractParams=function(a,o){const n=o.indexOf("?");if(n!==-1&&(o=o.slice(0,n)),a.endsWith("/*")){const s=a.slice(0,-2);return o.startsWith(s+"/")?{}:null}return t(a,o)};const i=R._renderNotFound.bind(R);let e="";R._renderNotFound=async function(a){return m()&&e!==a&&(e=a,await T(),R._matchRoute(a).route)?(e="",R._handleRouteChange()):(e="",m()&&$("#admin-sidebar").get(0)?.style.display==="none"?(E.toast("That link goes nowhere - here is your home page.",{type:"warning"}),R.navigate("/")):i(a))},vt(R),R.init({container:"#view-container",routes:I,views:l,default:"/",transitions:{enter:"fadeIn",leave:"fadeOut",duration:150}})})()});
@@ -1 +1 @@
1
- const r=/^\/api\/auth\/avatar\/[A-Za-z0-9_-]{1,80}-[a-f0-9]{16}\.webp$/;export function avatarUrl(a){const e=String(a?.avatar||"");return r.test(e)?e:""}export function showTopbarAvatar(a){try{S.set("auth_user",{...S.get("auth_user")||{},avatar:a})}catch{}const e=document.getElementById("topbar-user-name");if(!e)return;let t=document.getElementById("topbar-avatar");if(!a){t?.remove();return}t||(t=document.createElement("img"),t.id="topbar-avatar",t.className="topbar-avatar",t.alt="",e.before(t)),t.src=a}
1
+ import{initials as o}from"./users-arrange.js";const u=/^\/api\/auth\/avatar\/[A-Za-z0-9_-]{1,80}-[a-f0-9]{16}\.webp$/;export function avatarUrl(a){const e=String(a?.avatar||"");return u.test(e)?e:""}export function showTopbarAvatar(a){try{S.set("auth_user",{...S.get("auth_user")||{},avatar:a})}catch{}const e=document.getElementById("topbar-user-name");if(!e)return;let t=document.getElementById("topbar-avatar");if(!a){t?.remove();return}t||(t=document.createElement("img"),t.id="topbar-avatar",t.className="topbar-avatar",t.alt="",e.before(t)),t.src=a}let c;export function installAccountAvatar(a){const e=()=>{let r=a;try{r=S.get("auth_user")||a}catch{}renderAccountAvatar(r)};e(),c?.disconnect();const t=document.querySelector(".topbar-account-identity");t&&(c=new MutationObserver(e),c.observe(t,{subtree:!0,childList:!0,characterData:!0,attributes:!0,attributeFilter:["src"]}))}export function renderAccountAvatar(a){const e=document.getElementById("topbar-account-avatar");if(!e)return;const t=o(a),r=avatarUrl(a);if(!r){e.textContent=t;return}const n=document.createElement("img");n.className="topbar-avatar",n.alt="",n.addEventListener("error",()=>{e.textContent=t},{once:!0}),n.src=r,e.replaceChildren(n)}
@@ -0,0 +1 @@
1
+ import{renderTopbarNavigation as y,updateTopbarCounts as h}from"./topbar-navigation.js";export const COUNT_CACHE_MAX_AGE=5*6e4;const f=new Map,u=new Map;let a;export function countCacheKey(o,r,t,c=[]){const n=[],s=e=>{if(e){e.url&&e.countUrl&&n.push([e.url,e.countUrl,!!e.inventory]);for(const i of[...e.items||[],...e.children||[]])s(i)}};return c.forEach(e=>s(e.item||e)),"admin.counts.v1."+JSON.stringify([o?.id||"",[...r].sort(),t,n.sort()])}export function readCountCache(o,r=Date.now()){let t=f.get(o);if(!t)try{t=JSON.parse(sessionStorage.getItem(o))}catch{}return!t||!Number.isFinite(t.at)||r<t.at||r-t.at>COUNT_CACHE_MAX_AGE||!t.counts||typeof t.counts!="object"||Array.isArray(t.counts)?null:t.counts}export function writeCountCache(o,r,t=Date.now()){const c={};for(const[s,e]of Object.entries(r))!e||!Number.isFinite(e.count)||e.count<0||(c[s]={count:e.count,label:String(e.label||""),tone:e.tone||"info",showZero:e.showZero===!0,inventory:e.inventory===!0});const n={at:t,counts:c};f.set(o,n);try{sessionStorage.setItem(o,JSON.stringify(n))}catch{}}export function loadCountSnapshot(o,r){return u.has(o)||u.set(o,Promise.resolve().then(r).then(t=>(writeCountCache(o,t),t)).finally(()=>u.delete(o))),u.get(o)}export function countSnapshot(o,r){const t=new Map,c=n=>{if(n){n.url&&n.countUrl&&t.set(n.url,!!n.inventory);for(const s of[...n.items||[],...n.children||[]])c(s)}};return r.forEach(n=>c(n.item||n)),Object.fromEntries(Object.entries(o).map(([n,s])=>[n,s?{...s,aggregate:t.has(n)&&!t.get(n)&&!s.inventory}:null]))}export async function beginSidebarCounts({user:o,permissions:r,adminScope:t,registered:c,tree:n,actions:s,fetcher:e}){const i={key:countCacheKey(o,r,t,c),registered:c};a=i;const l=readCountCache(i.key)||{};y(n,{...s,counts:countSnapshot(l,c)});try{const p=await loadCountSnapshot(i.key,e);return a===i&&h(countSnapshot(p,c),{replace:!0}),p}catch{return l}}export function publishSidebarCount(o,r){if(!a)return;h(countSnapshot({[o]:r},a.registered));const t=readCountCache(a.key)||{};r?t[o]=r:delete t[o];const c=f.get(a.key)?.at||Date.now();writeCountCache(a.key,t,c)}
@@ -1,7 +1,7 @@
1
- import{api as g,getUser as T}from"../api.js";import{isPathAllowed as he}from"./admin-scope.js";import{colourToCss as J,applyFloat as ge,applyHighlight as be,itemHighlightAttrs as ye}from"/public/js/menu-decor.mjs?v=20261014-menu-entrance";import{placeTools as ve,ensureLockedTools as xe,managePluginsItem as $e,stripItemByUrl as we,insertFoldersBeforeSystem as Se,pruneEmptyToolsFolder as ke,sidebarStateKey as Q,canAny as z,filterByPermission as qe,MANAGE_PLUGINS_URL as ee}from"./sidebar-grouping.js";import{arrangeButtonMarkup as Ce,canArrange as Ae,startArrange as Fe}from"./sidebar-arrange.js";import{collapseButtonMarkup as Le,wireSidebarSize as Ee,COLLAPSED_WIDTH as Me}from"./sidebar-size.js";import{FREQUENT_MAX as te,addFrequent as Te,frequentFolder as Be,moveFrequent as ne,readFrequent as G,readFrequentHidden as He,removeFrequent as je,saveFrequent as Ne,syncFrequent as Pe,writeFrequent as Re,writeFrequentHidden as se}from"./sidebar-frequent.js";import{hotkeyFor as oe,hotkeyTitle as _e,setHotkeyTree as Ie}from"./hotkeys-ui.js";import{hotkeyLabel as Oe}from"./hotkeys.js";function f(e){return String(e??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}const Ue=[{text:"Dashboard",url:"#/",icon:"home"},{text:"Site menus",url:"#/menus",icon:"menu",permission:"menus"}];async function ze(e){if(!z(e,"projects"))return[];let t=[];try{t=await g.projects.listWithCounts()}catch{return[]}if(!Array.isArray(t))return[];const s=[{key:"pages",text:"Pages",icon:"file-text",path:"/pages"},{key:"collections",text:"Collections",icon:"database",path:"/collections"},{key:"forms",text:"Forms",icon:"layout",path:"/forms"},{key:"actions",text:"Actions",icon:"zap",path:"/actions"},{key:"menus",text:"Site menus",icon:"menu",path:"/menus"},{key:"blocks",text:"Blocks",icon:"box",path:"/blocks"},{key:"components",text:"Components",icon:"component",path:"/components"},{key:"views",text:"Views",icon:"eye",path:"/views"},{key:"roles",text:"Roles",icon:"shield",path:"/roles"},{key:"users",text:"Users",icon:"users",path:"/users"},{key:"apis",text:"APIs",icon:"code",path:"/apis"}];return t.map(o=>{const d="#/projects/"+encodeURIComponent(o.slug),i=o.counts||{},c=[{text:"Overview",url:d,icon:o.icon||"folder"}];for(const r of s){const a=Number(i[r.key])||0;a<=0||c.push({text:`${r.text} (${a})`,url:d+r.path,icon:r.icon})}c.push({text:"Settings",url:d+"/settings",icon:"settings"});const u=o.enabled===!1;return{text:o.name||o.slug,key:`project.${o.slug}`,icon:o.icon||"folder",items:c,...u&&{colour:"neutral",badge:{text:"off"}}}})}function We(e,t){for(const s of e)if(!s.hidden&&(s.key==="projects"||!s.key&&(s.text||"").toLowerCase()==="projects")){s.items=Array.isArray(s.items)?s.items.slice():[],s.items.push(...t);return}}function ie(e,t){const s=re.includes(t.tone)?t.tone:"info",o=t.label||String(t.count);t.details?R.set(e,t.details):R.delete(e);const n=!t.inventory&&F.some(d=>d.url===e&&!d.inventory)?" data-live":"";return`<span class="sidebar-badge sidebar-badge--${s}" data-count-for="${f(e)}"${n} data-badge-label="${f(o)}" aria-label="${f(o)}">${f(String(t.count))}</span>`}function ae(e){for(const t of e.querySelectorAll("details")){const s=t.querySelector(":scope > summary");if(!s)continue;let o=0,n=!1;const d=[];for(const a of t.querySelectorAll(":scope > .sidebar-children .sidebar-badge[data-live]")){const m=Number(a.textContent)||0;m&&(o+=m,n||(n=a.classList.contains("sidebar-badge--danger")),d.push({text:a.closest("a")?.querySelector(".sidebar-text")?.textContent.trim()??"",meta:a.dataset.badgeLabel,tone:a.classList.contains("sidebar-badge--danger")?"danger":void 0}))}const i=`folder:${t.dataset.stateKey||s.textContent.trim()}`;let c=s.querySelector(":scope > .sidebar-badge--sum");if(!o){c?.remove(),R.delete(i);continue}c||(c=document.createElement("span"),s.querySelector(".sidebar-text")?.after(c));const u=s.querySelector(".sidebar-text")?.textContent.trim()||"This folder",r=d.map(a=>`${a.text}: ${a.meta}`).join(" \xB7 ");c.className=`sidebar-badge sidebar-badge--sum sidebar-badge--${n?"danger":"info"}`,c.dataset.countFor=i,c.dataset.badgeLabel=r,c.setAttribute("aria-label",r),c.textContent=String(o),R.set(i,{title:u,items:d})}}const R=new Map;function De(e,t){if(!e.url||!t)return"";const s=t[e.url];return!s||!(s.count>0)&&!s.showZero?"":ie(e.url,s)}const re=["info","attention","danger","live"],Ge={"#/pages":["page","pages"],"#/media":["file in the media library","files in the media library"],"#/menus":["menu","menus"],"#/context-menus":["context menu","context menus"],"#/theme":["element override in the theme","element overrides in the theme"],"#/collections":["collection","collections"],"#/forms":["form","forms"],"#/views":["view","views"],"#/actions":["action","actions"],"#/blocks":["block","blocks"],"#/components":["component","components"],"#/users":["user","users"],"#/plugins":["plugin installed","plugins installed"],"#/system/notifications":["unread notification","unread notifications"]};function K(e,{fallbackLabel:t="",tone:s="info"}={}){const o=Number(typeof e=="object"&&e!==null?e.count:e);if(!Number.isFinite(o)||o<0)return null;const n=typeof e?.label=="string"&&e.label||(t?`${o} - ${t}`:String(o)),d={count:Math.round(o),label:n,tone:re.includes(e?.tone)?e.tone:s};return e?.details&&typeof e.details=="object"&&(d.details=e.details),e?.inventory===!0&&(d.inventory=!0),e?.showZero===!0&&(d.showZero=!0),d}function le(e,t,s=null,{inFrequent:o=!1}={}){if(e&&e.type==="separator")return'<hr class="sidebar-divider">';if(e&&e.type==="theme-switcher")return"";if(e&&e.type==="spacer"){const y=["xs","sm","md","lg","xl","flex"].includes(e.size)?e.size:"md";return`<div class="sidebar-spacer sidebar-spacer--${f(y)}" aria-hidden="true"></div>`}const n=String(e.text||"?").trim().charAt(0).toUpperCase()||"?",d=e.icon?`<span data-icon="${f(e.icon)}"></span>`:`<span class="sidebar-initial" aria-hidden="true">${f(n)}</span>`,i=f(e.text||""),c=e.url?f(e.url):"",u=Array.isArray(e.items)&&e.items.length>0,r=e.colour?J(e.colour):"",a=ye(e),m=[a.hover&&` data-menu-item-hover="${f(a.hover)}"`,a.active&&` data-menu-item-active="${f(a.active)}"`].filter(Boolean).join(""),b=[r&&`color:${f(r)}`,a.accent&&`--dm-menu-highlight:${f(a.accent)}`].filter(Boolean).join(";"),v=b?` style="${b}"`:"",w=e.url?_e(e.url,e.text||"",{inFrequent:o}):"",k=w?` title="${f(w)}"`:"";let A="";if(e.badge&&e.badge.text!=null&&e.badge.text!==""){const y=e.badge.variant?J(e.badge.variant):"";A=`<span class="dm-menu-badge"${y?` style="background:${f(y)};color:var(--dm-text-inverse,#fff)"`:""}>${f(String(e.badge.text))}</span>`}if(e.frequent&&e.empty){const y=Q(e,s),C=S.get(y)!==!1;return`<details data-state-key="${f(y)}"${C?" open":""} data-frequent data-frequent-empty>
1
+ import{api as h,getUser as F}from"../api.js";import{beginSidebarCounts as ye,publishSidebarCount as ve}from"./sidebar-count-cache.js";import{isPathAllowed as xe}from"./admin-scope.js";import{colourToCss as J,applyFloat as $e,applyHighlight as we,itemHighlightAttrs as Se}from"/public/js/menu-decor.mjs?v=20261014-menu-entrance";import{placeTools as ke,ensureLockedTools as Ce,managePluginsItem as qe,stripItemByUrl as Ae,insertFoldersBeforeSystem as Fe,pruneEmptyToolsFolder as Le,sidebarStateKey as Q,canAny as z,filterByPermission as Ee,MANAGE_PLUGINS_URL as ee}from"./sidebar-grouping.js";import{arrangeButtonMarkup as Be,canArrange as Me,startArrange as Te}from"./sidebar-arrange.js";import{collapseButtonMarkup as He,wireSidebarSize as je,COLLAPSED_WIDTH as Ne}from"./sidebar-size.js";import{FREQUENT_MAX as te,addFrequent as Oe,frequentFolder as Pe,moveFrequent as ne,readFrequent as G,readFrequentHidden as Ie,removeFrequent as Re,saveFrequent as _e,syncFrequent as Ue,writeFrequent as ze,writeFrequentHidden as se}from"./sidebar-frequent.js";import{hotkeyFor as oe,hotkeyTitle as We,setHotkeyTree as De}from"./hotkeys-ui.js";import{hotkeyLabel as Ge}from"./hotkeys.js";function f(e){return String(e??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}const Ke=[{text:"Dashboard",url:"#/",icon:"home"},{text:"Site menus",url:"#/menus",icon:"menu",permission:"menus"}];async function Ve(e){if(!z(e,"projects"))return[];let t=[];try{t=await h.projects.listWithCounts()}catch{return[]}if(!Array.isArray(t))return[];const s=[{key:"pages",text:"Pages",icon:"file-text",path:"/pages"},{key:"collections",text:"Collections",icon:"database",path:"/collections"},{key:"forms",text:"Forms",icon:"layout",path:"/forms"},{key:"actions",text:"Actions",icon:"zap",path:"/actions"},{key:"menus",text:"Site menus",icon:"menu",path:"/menus"},{key:"blocks",text:"Blocks",icon:"box",path:"/blocks"},{key:"components",text:"Components",icon:"component",path:"/components"},{key:"views",text:"Views",icon:"eye",path:"/views"},{key:"roles",text:"Roles",icon:"shield",path:"/roles"},{key:"users",text:"Users",icon:"users",path:"/users"},{key:"apis",text:"APIs",icon:"code",path:"/apis"}];return t.map(o=>{const d="#/projects/"+encodeURIComponent(o.slug),i=o.counts||{},l=[{text:"Overview",url:d,icon:o.icon||"folder"}];for(const a of s){const r=Number(i[a.key])||0;r<=0||l.push({text:`${a.text} (${r})`,url:d+a.path,icon:a.icon})}l.push({text:"Settings",url:d+"/settings",icon:"settings"});const u=o.enabled===!1;return{text:o.name||o.slug,key:`project.${o.slug}`,icon:o.icon||"folder",items:l,...u&&{colour:"neutral",badge:{text:"off"}}}})}function Xe(e,t){for(const s of e)if(!s.hidden&&(s.key==="projects"||!s.key&&(s.text||"").toLowerCase()==="projects")){s.items=Array.isArray(s.items)?s.items.slice():[],s.items.push(...t);return}}function ie(e,t){const s=re.includes(t.tone)?t.tone:"info",o=t.label||String(t.count);t.details?I.set(e,t.details):I.delete(e);const n=!t.inventory&&L.some(d=>d.url===e&&!d.inventory)?" data-live":"";return`<span class="sidebar-badge sidebar-badge--${s}" data-count-for="${f(e)}"${n} data-badge-label="${f(o)}" aria-label="${f(o)}">${f(String(t.count))}</span>`}function ae(e){for(const t of e.querySelectorAll("details")){const s=t.querySelector(":scope > summary");if(!s)continue;let o=0,n=!1;const d=[];for(const r of t.querySelectorAll(":scope > .sidebar-children .sidebar-badge[data-live]")){const m=Number(r.textContent)||0;m&&(o+=m,n||(n=r.classList.contains("sidebar-badge--danger")),d.push({text:r.closest("a")?.querySelector(".sidebar-text")?.textContent.trim()??"",meta:r.dataset.badgeLabel,tone:r.classList.contains("sidebar-badge--danger")?"danger":void 0}))}const i=`folder:${t.dataset.stateKey||s.textContent.trim()}`;let l=s.querySelector(":scope > .sidebar-badge--sum");if(!o){l?.remove(),I.delete(i);continue}l||(l=document.createElement("span"),s.querySelector(".sidebar-text")?.after(l));const u=s.querySelector(".sidebar-text")?.textContent.trim()||"This folder",a=d.map(r=>`${r.text}: ${r.meta}`).join(" \xB7 ");l.className=`sidebar-badge sidebar-badge--sum sidebar-badge--${n?"danger":"info"}`,l.dataset.countFor=i,l.dataset.badgeLabel=a,l.setAttribute("aria-label",a),l.textContent=String(o),I.set(i,{title:u,items:d})}}const I=new Map;function Ze(e,t){if(!e.url||!t)return"";const s=t[e.url];return!s||!(s.count>0)&&!s.showZero?"":ie(e.url,s)}const re=["info","attention","danger","live"],Ye={"#/pages":["page","pages"],"#/media":["file in the media library","files in the media library"],"#/menus":["menu","menus"],"#/context-menus":["context menu","context menus"],"#/theme":["element override in the theme","element overrides in the theme"],"#/collections":["collection","collections"],"#/forms":["form","forms"],"#/views":["view","views"],"#/actions":["action","actions"],"#/blocks":["block","blocks"],"#/components":["component","components"],"#/users":["user","users"],"#/plugins":["plugin installed","plugins installed"],"#/system/notifications":["unread notification","unread notifications"]};function K(e,{fallbackLabel:t="",tone:s="info"}={}){const o=Number(typeof e=="object"&&e!==null?e.count:e);if(!Number.isFinite(o)||o<0)return null;const n=typeof e?.label=="string"&&e.label||(t?`${o} - ${t}`:String(o)),d={count:Math.round(o),label:n,tone:re.includes(e?.tone)?e.tone:s};return e?.details&&typeof e.details=="object"&&(d.details=e.details),e?.inventory===!0&&(d.inventory=!0),e?.showZero===!0&&(d.showZero=!0),d}function le(e,t,s=null,{inFrequent:o=!1}={}){if(e&&e.type==="separator")return'<hr class="sidebar-divider">';if(e&&e.type==="theme-switcher")return"";if(e&&e.type==="spacer"){const b=["xs","sm","md","lg","xl","flex"].includes(e.size)?e.size:"md";return`<div class="sidebar-spacer sidebar-spacer--${f(b)}" aria-hidden="true"></div>`}const n=String(e.text||"?").trim().charAt(0).toUpperCase()||"?",d=e.icon?`<span data-icon="${f(e.icon)}"></span>`:`<span class="sidebar-initial" aria-hidden="true">${f(n)}</span>`,i=f(e.text||""),l=e.url?f(e.url):"",u=Array.isArray(e.items)&&e.items.length>0,a=e.colour?J(e.colour):"",r=Se(e),m=[r.hover&&` data-menu-item-hover="${f(r.hover)}"`,r.active&&` data-menu-item-active="${f(r.active)}"`].filter(Boolean).join(""),y=[a&&`color:${f(a)}`,r.accent&&`--dm-menu-highlight:${f(r.accent)}`].filter(Boolean).join(";"),v=y?` style="${y}"`:"",w=e.url?We(e.url,e.text||"",{inFrequent:o}):"",k=w?` title="${f(w)}"`:"";let q="";if(e.badge&&e.badge.text!=null&&e.badge.text!==""){const b=e.badge.variant?J(e.badge.variant):"";q=`<span class="dm-menu-badge"${b?` style="background:${f(b)};color:var(--dm-text-inverse,#fff)"`:""}>${f(String(e.badge.text))}</span>`}if(e.frequent&&e.empty){const b=Q(e,s),A=S.get(b)!==!1;return`<details data-state-key="${f(b)}"${A?" open":""} data-frequent data-frequent-empty>
2
2
  <summary${v}>${d} <span class="sidebar-text">${i}</span></summary>
3
3
  <div class="sidebar-children"><p class="sidebar-frequent-empty">Right-click any Tool and choose <strong>Add to Frequent</strong> to keep it here.</p></div>
4
- </details>`}if(u){const y=Q(e,s),C=S.get(y)!==!1,B=e.items.map(L=>le(L,t,y,{inFrequent:!!e.frequent})).join(""),_=e.frequent?' data-frequent title="Your Frequent Tools - right-click any Tool to add or remove it"':"";return`<details data-state-key="${f(y)}"${C?" open":""}${_}>
5
- <summary${v}${k}>${d} <span class="sidebar-text">${i}</span>${A}</summary>
4
+ </details>`}if(u){const b=Q(e,s),A=S.get(b)!==!1,B=e.items.map(N=>le(N,t,b,{inFrequent:!!e.frequent})).join(""),j=e.frequent?' data-frequent title="Your Frequent Tools - right-click any Tool to add or remove it"':"";return`<details data-state-key="${f(b)}"${A?" open":""}${j}>
5
+ <summary${v}${k}>${d} <span class="sidebar-text">${i}</span>${q}</summary>
6
6
  <div class="sidebar-children">${B}</div>
7
- </details>`}return`<a href="${c}" class="sidebar-link" data-url="${c}"${v}${m}${k}>${d} <span class="sidebar-text">${i}</span>${De(e,t)}${A}</a>`}async function Ke(e=[],t=[],s=null){const o=p=>p.then(x=>Array.isArray(x)?x.length:Array.isArray(x?.entries)?x.entries.length:0).catch(()=>0);F=Ze(e,s);const n=new Set(F.map(p=>p.url)),d={pages:"#/pages",media:"#/media",menus:"#/menus","context-menus":"#/context-menus",theme:"#/theme",collections:"#/collections",forms:"#/forms",views:"#/views",actions:"#/actions",blocks:"#/blocks",components:"#/components",users:"#/users",plugins:"#/plugins",notifications:"#/system/notifications"},i=(p,x)=>z(t,p)&&!n.has(d[p])?x():Promise.resolve(0),[c,u,r,a,m,b,v,w,k,A,y,C,B,_]=await Promise.all([i("pages",()=>o(g.pages.list())),i("media",()=>o(g.media.list())),i("menus",()=>o(g.menus.list())),i("context-menus",()=>o(g.contextMenus.list())),i("theme",()=>g.theme.get().then(p=>(p?.overrides||[]).length).catch(()=>0)),i("collections",()=>o(g.collections.list())),i("forms",()=>o(g.forms.list())),i("views",()=>o(g.views.list())),i("actions",()=>o(g.actions.list())),i("blocks",()=>o(g.blocks.list())),i("components",()=>o(g.components.list())),i("users",()=>o(g.users.list())),i("plugins",()=>o(g.plugins.list())),i("notifications",()=>g.system?.notifications?.unreadCount?.().then(p=>p?.count??0).catch(()=>0)??Promise.resolve(0))]),L={};await Promise.all(F.map(async p=>{const x=await ce(p);x&&(L[p.url]=x)}));const O={"#/pages":c,"#/media":u,"#/menus":r,"#/context-menus":a,"#/theme":m,"#/collections":b,"#/forms":v,"#/views":w,"#/actions":k,"#/blocks":A,"#/components":y,"#/users":C,"#/plugins":B,"#/system/notifications":_},W={};for(const[p,x]of Object.entries(O)){if(n.has(p))continue;const[D,U]=Ge[p]??["item","items"],j=K(x);j&&(W[p]={...j,label:`${j.count} ${j.count===1?D:U}`})}return{...W,...L}}let F=[];const Ve="dm:sidebar-count",Xe=6e4;function Ze(e=[],t=null){const s=[],o=n=>{if(n&&!(t&&typeof n.url=="string"&&n.url.startsWith("#/")&&!he(t,n.url.slice(1)))){n.url&&typeof n.countUrl=="string"&&n.countUrl&&s.push({url:n.url,countUrl:n.countUrl,text:n.text||"",countLabel:n.countLabel||"",inventory:n.inventory===!0});for(const d of[...n.children||[],...n.items||[]])o(d)}};for(const n of e??[])o(n?.item??n);return s}async function ce(e){try{const t=new Date,s=`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")}`,o=e.countUrl+(e.countUrl.includes("?")?"&":"?")+`today=${s}`;return K(await H.get(o),{fallbackLabel:e.countLabel||e.text})}catch{return null}}function de(e,t,s){const o=[...e.querySelectorAll("a.sidebar-link")].filter(n=>n.dataset.url===t);if(o.length){for(const n of o){const d=n.querySelector(".sidebar-badge[data-count-for]");if(!s||!(s.count>0)&&!s.showZero)d?.remove();else{const i=document.createRange();i.selectNodeContents(n);const c=i.createContextualFragment(ie(t,s)).firstElementChild;d?d.replaceWith(c):n.querySelector(".sidebar-text")?.after(c)}}V.set(t,s),ae(e)}}const V=new Map;async function X(e,t=null){const s=t?F.filter(o=>o.url===t):F;await Promise.all(s.map(async o=>{const n=await ce(o),d=V.get(o.url);JSON.stringify(d??null)!==JSON.stringify(n)&&de(e,o.url,n)}))}function Ye(e){e.dataset.liveCounts||(e.dataset.liveCounts="1",window.addEventListener(Ve,t=>{const s=t.detail||{};if(s.url)if(s.count!==void 0){const o=F.find(n=>n.url===s.url);de(e,s.url,K(s,{fallbackLabel:o?.countLabel||o?.text||""}))}else X(e,s.url)}),setInterval(()=>{!document.hidden&&document.body.contains(e)&&X(e)},Xe),document.addEventListener("visibilitychange",()=>{document.hidden||X(e)}),Je(e))}function ue(e,t,s){const o=(i,c,u)=>{const r=document.createElement(i);return c&&(r.className=c),u!=null&&(r.textContent=String(u)),r};if(!s){e.textContent=t;return}e.appendChild(o("strong","dm-badge-pop-title",s.title||t)),(s.rows?.length||!s.items?.length)&&e.appendChild(o("p","dm-badge-pop-sub",t));const n=Array.isArray(s.rows)?s.rows.slice(0,6):[];if(n.length){const i=o("dl","dm-badge-pop-rows");for(const c of n)i.appendChild(o("dt",null,c.label)),i.appendChild(o("dd",c.tone==="danger"?"is-danger":null,c.value));e.appendChild(i)}const d=Array.isArray(s.items)?s.items.slice(0,6):[];if(d.length){const i=o("ul","dm-badge-pop-items");for(const c of d){const u=o("li",c.tone==="danger"?"is-danger":null);u.appendChild(o("span","dm-badge-pop-text",c.text)),c.meta&&u.appendChild(o("span","dm-badge-pop-meta",c.meta)),i.appendChild(u)}e.appendChild(i)}else s.empty&&e.appendChild(o("p","dm-badge-pop-empty",s.empty))}function Je(e){let t=null,s=null;const o=()=>e.classList.contains("is-collapsed"),n=()=>{clearTimeout(s),t?.remove(),t=null},d=(r,a)=>{n(),s=setTimeout(()=>{t=document.createElement("div"),t.className="dm-help-pop dm-badge-pop",t.setAttribute("role","tooltip"),a(t),document.body.appendChild(t);const m=r.getBoundingClientRect(),b=t.getBoundingClientRect(),v=Math.min(m.right+10,innerWidth-b.width-8);t.style.left=`${Math.max(8,v)}px`,t.style.top=`${Math.max(8,Math.min(m.top+m.height/2-b.height/2,innerHeight-b.height-8))}px`},150)},i=r=>{const a=r?.dataset.badgeLabel;if(!a)return n();d(r,m=>ue(m,a,R.get(r.dataset.countFor)))},c=r=>{const a=r.querySelector(":scope > .sidebar-text")?.textContent.trim()||"",m=r.querySelector(":scope > .sidebar-badge[data-badge-label]:not([hidden])");d(r,b=>{const v=m&&R.get(m.dataset.countFor);if(v)return ue(b,m.dataset.badgeLabel,{...v,title:v.title||a});if(!m){b.textContent=a;return}const w=document.createElement("strong");w.className="dm-badge-pop-title",w.textContent=a;const k=document.createElement("p");k.className="dm-badge-pop-sub",k.textContent=m.dataset.badgeLabel,b.append(w,k)})},u=r=>{const a=r.closest?.("a.sidebar-link, summary");return a&&e.contains(a)?a:null};e.addEventListener("mouseover",r=>{if(o()){const m=u(r.target);m&&!m.contains(r.relatedTarget)&&c(m);return}const a=r.target.closest?.(".sidebar-badge[data-badge-label]");a&&i(a)}),e.addEventListener("mouseout",r=>{if(o()){const a=u(r.target);a&&!a.contains(r.relatedTarget)&&n();return}r.target.closest?.(".sidebar-badge[data-badge-label]")&&n()}),e.addEventListener("focusin",r=>{const a=r.target.closest?.("a, summary");if(o()&&a&&e.contains(a)&&a.querySelector(":scope > .sidebar-text"))return c(a);const m=a?.querySelector(":scope > .sidebar-badge[data-badge-label]:not([hidden])");m?i(m):n()}),e.addEventListener("focusout",n),e.addEventListener("click",n),window.addEventListener("scroll",n,!0),window.addEventListener("hashchange",n)}async function Qe(e=[],t=null){if(t?.title)return t;if(!z(e,"settings"))return{title:"Domma CMS"};try{const s=await g.settings.get();return{...s?.adminBrand,title:s?.adminBrand?.title||s?.title||"Domma CMS"}}catch{return{title:"Domma CMS"}}}export async function renderAdminSidebar({mount:e,permissions:t,adminScope:s=null,brand:o=null}){const n=$(e).get(0);if(!n)return;const d=Pe(g,T()).catch(()=>{});let i,c=null,u=null,r=null,a=null,m=null;try{const l=await g.get("/sidebar/menu");i=Array.isArray(l?.items)?l.items:null,c=l?.variant||null,u=l?.position||null,r=l?.style||null,a=l?.float||null,m=l?.highlight||null}catch{i=null}(!i||!i.some(l=>l&&(!l.hidden||l.restricted)))&&(console.warn("[admin-sidebar] No admin-sidebar menu found; using fallback tree"),i=Ue.slice());let b=[];try{b=await H.get("/api/sidebar/registered-items")||[]}catch{}i=we(i,ee),i=ve(i,b.filter(l=>(l?.item??l)?.url!==ee)),i=xe(i),i=Se(i,[$e()]);const v=await ze(t);v.length&&We(i,v),i=qe(i,t,s),i=ke(i),await d;const w=Be(i,G(T()),{hidden:He(T())});w&&(i=[w,...i]),Ie(i);const[k,A]=await Promise.all([Ke(b.filter(l=>z(t,l?.item?.permission)),t,s).catch(()=>({})),Qe(t,o)]),y=c?` dm-admin-sidebar--${f(c)}`:"";function C(l,q="px"){if(l==null)return l;const h=String(l).trim();return/^\d+(\.\d+)?$/.test(h)?`${h}${q}`:h}let B="";if(r){const l=[];r.fontFamily&&l.push(`font-family: ${r.fontFamily}, sans-serif`),r.fontSize&&l.push(`font-size: ${C(r.fontSize)}`),r.fontWeight&&l.push(`font-weight: ${r.fontWeight}`),r.letterSpacing&&l.push(`letter-spacing: ${C(r.letterSpacing,"em")}`);const q=[];if(l.length&&q.push(`#admin-sidebar .dm-admin-sidebar, #admin-sidebar .dm-admin-sidebar .sidebar-link, #admin-sidebar .dm-admin-sidebar summary, #admin-sidebar .dm-admin-sidebar .sidebar-text { ${l.join("; ")} }`),r.iconSize){const h=C(r.iconSize);q.push(`#admin-sidebar .dm-admin-sidebar [data-icon], #admin-sidebar .dm-admin-sidebar [data-icon] svg { width: ${h} !important; height: ${h} !important; }`)}q.length&&(B=`<style data-admin-sidebar-style>${q.join(" ")}</style>`)}const _=Ae(t)?Ce():"",L=String(A.logo||"").trim(),O=/^(?:\/(?!\/)|https?:\/\/)/i.test(L)?L:"",p=`<div class="dm-admin-sidebar-header">${O?`<img src="${f(O)}" alt="" style="width:28px;height:28px;object-fit:contain;flex-shrink:0;">`:`<span data-icon="${f(A.icon||"layout")}"></span>`}<span class="dm-admin-sidebar-title">${f(A.title)}</span>${_}${Le()}</div>`,x=i.some(l=>l&&l.type==="spacer"&&l.size==="flex")?" dm-admin-sidebar--has-flex-spacer":"",D=`${B}<nav class="dm-admin-sidebar${y}${x}">${p}${i.map(l=>le(l,k)).join("")}</nav>`,U=document.createRange();U.selectNodeContents(n);const j=U.createContextualFragment(D);n.replaceChildren(j),Domma.icons.scan(n),n.querySelector(".dm-admin-sidebar-arrange")?.addEventListener("click",()=>Fe(n));for(const l of F)V.set(l.url,k[l.url]??null);ae(n),Ye(n),n.removeAttribute("data-menu-hover"),n.removeAttribute("data-menu-active"),n.style.removeProperty("--dm-menu-highlight"),be(n,{highlight:m});const N=document.querySelector(".dashboard-wrapper");["position","top","bottom","left","right","zIndex","maxHeight","transform"].forEach(l=>{n.style[l]=""}),n.classList.remove("dm-menu-floating"),N&&(N.style.paddingLeft="",N.style.paddingRight=""),n.__dmGutter=()=>{if(u!=="floating"||!N)return;const l=a&&a.anchor||"TL",q=Number.isFinite(Number(a?.offsetX))?Number(a.offsetX):16,h=n.classList.contains("is-collapsed")?Me:parseInt(n.style.width,10)||n.getBoundingClientRect().width||260,P=Math.round(h+q*2)+"px";l==="R"||l==="TR"||l==="BR"?N.style.paddingRight=P:N.style.paddingLeft=P},u==="floating"&&ge(n,{position:"floating",float:a||{}}),n.querySelectorAll("details").forEach(l=>{l.addEventListener("toggle",function(){const q=this.getAttribute("data-state-key");q&&S.set(q,this.open);const h=this.querySelector(":scope > .sidebar-children");if(h)if(this.open){const P=h.scrollHeight;h.style.maxHeight="0",requestAnimationFrame(()=>{h.style.maxHeight=P+"px",h.addEventListener("transitionend",function pe(){h.style.maxHeight="none",h.removeEventListener("transitionend",pe)})})}else{const P=h.scrollHeight;h.style.maxHeight=P+"px",requestAnimationFrame(()=>{h.style.maxHeight="0"})}})}),Ee(n),st(n),n.dataset.routeWired||(n.dataset.routeWired="1",M.subscribe("router:afterChange",()=>n.__dmSetActive?.()));function Y(){const l=/^#\/(dashboards|my-dashboard)\b/.test(location.hash)?"#/":location.hash||"#/";$(n).find(".sidebar-link").removeClass("active"),$(n).find(`.sidebar-link[data-url="${l}"]`).addClass("active")}Y(),n.__dmSetActive=Y}function me(){try{document.dispatchEvent(new CustomEvent("dm:sidebar-rebuild"))}catch{}}function Z(e){return`${location.origin}${location.pathname}${e}`}function I(e,t){const s=T(),o=e(G(s));if(!Re(s,o)){E.toast("Frequent could not be saved - this browser is blocking storage.",{type:"error"});return}o.length&&se(s,!1),fe(s),t&&E.toast(t,{type:"success",duration:2500}),me()}function fe(e){Ne(g,e).catch(()=>E.toast("Frequent is saved in this browser only - the server could not keep it.",{type:"warning"}))}function et(e){if(!se(T(),e)){E.toast("Frequent could not be saved - this browser is blocking storage.",{type:"error"});return}fe(T()),E.toast(e?"Frequent hidden. Add a Tool to it from its right-click menu to bring it back.":"Frequent shown.",{type:"success",duration:3500}),me()}function tt(e){const t=e.dataset.url;if(!t)return[];const s=e.querySelector(".sidebar-text")?.textContent.trim()||t,o=G(T()),n=o.includes(t),d=!!e.closest("details[data-frequent]"),i=o.indexOf(t),c=!n&&o.length>=te;return[{header:s},{label:"Open",icon:"arrow-right",...oe(t)&&{shortcut:Oe(oe(t))},action:()=>{location.hash=t}},{label:"Open in a new tab",icon:"external-link",action:()=>window.open(Z(t),"_blank","noopener")},{type:"divider"},n?{label:"Remove from Frequent",icon:"star",action:()=>I(u=>je(u,t),`${s} removed from Frequent.`)}:{label:c?`Frequent is full (${te})`:"Add to Frequent",icon:"star",disabled:c,action:()=>I(u=>Te(u,t),`${s} added to Frequent.`)},...d?[{label:"Move up",icon:"arrow-up",disabled:i<=0,action:()=>I(u=>ne(u,t,-1))},{label:"Move down",icon:"arrow-down",disabled:i<0||i>=o.length-1,action:()=>I(u=>ne(u,t,1))}]:[],{type:"divider"},{label:"Copy link",icon:"link",action:async()=>{try{await navigator.clipboard.writeText(Z(t)),E.toast("Link copied.",{type:"success",duration:2e3})}catch{E.toast(Z(t),{type:"info",duration:8e3})}}}]}function nt(e,t){const s=e.closest("details"),o=e.querySelector(".sidebar-text")?.textContent.trim()||"Folder",n=d=>t.querySelectorAll("details").forEach(i=>{i.open!==d&&(i.open=d)});return[{header:o},{label:s?.open?"Close":"Open",icon:s?.open?"chevron-up":"chevron-down",action:()=>{s&&(s.open=!s.open)}},{label:"Open every folder",icon:"chevrons-down",action:()=>n(!0)},{label:"Close every folder",icon:"chevrons-up",action:()=>n(!1)},...s?.hasAttribute("data-frequent-empty")?[{type:"divider"},{label:"Hide Frequent until I add a Tool",icon:"eye-off",action:()=>et(!0)}]:s?.hasAttribute("data-frequent")?[{type:"divider"},{label:"Clear Frequent",icon:"x",action:()=>I(()=>[],"Frequent cleared.")}]:[]]}function st(e){e.dataset.ctxWired||typeof E>"u"||!E.contextMenu||(e.dataset.ctxWired="1",E.contextMenu(e,{match:"a.sidebar-link, details > summary",inherit:!1,density:"compact",items:t=>t.matches("summary")?nt(t,e):tt(t)}))}
7
+ </details>`}return`<a href="${l}" class="sidebar-link" data-url="${l}"${v}${m}${k}>${d} <span class="sidebar-text">${i}</span>${Ze(e,t)}${q}</a>`}async function Je(e=[],t=[],s=null){const o=g=>g.then(x=>Array.isArray(x)?x.length:Array.isArray(x?.entries)?x.entries.length:0).catch(()=>0);L=tt(e,s);const n=new Set(L.map(g=>g.url)),d={pages:"#/pages",media:"#/media",menus:"#/menus","context-menus":"#/context-menus",theme:"#/theme",collections:"#/collections",forms:"#/forms",views:"#/views",actions:"#/actions",blocks:"#/blocks",components:"#/components",users:"#/users",plugins:"#/plugins",notifications:"#/system/notifications"},i=(g,x)=>z(t,g)&&!n.has(d[g])?x():Promise.resolve(0),[l,u,a,r,m,y,v,w,k,q,b,A,B,j]=await Promise.all([i("pages",()=>o(h.pages.list())),i("media",()=>o(h.media.list())),i("menus",()=>o(h.menus.list())),i("context-menus",()=>o(h.contextMenus.list())),i("theme",()=>h.theme.get().then(g=>(g?.overrides||[]).length).catch(()=>0)),i("collections",()=>o(h.collections.list())),i("forms",()=>o(h.forms.list())),i("views",()=>o(h.views.list())),i("actions",()=>o(h.actions.list())),i("blocks",()=>o(h.blocks.list())),i("components",()=>o(h.components.list())),i("users",()=>o(h.users.list())),i("plugins",()=>o(h.plugins.list())),i("notifications",()=>h.system?.notifications?.unreadCount?.().then(g=>g?.count??0).catch(()=>0)??Promise.resolve(0))]),N={};await Promise.all(L.map(async g=>{const x=await ce(g);x&&(N[g.url]=x)}));const U={"#/pages":l,"#/media":u,"#/menus":a,"#/context-menus":r,"#/theme":m,"#/collections":y,"#/forms":v,"#/views":w,"#/actions":k,"#/blocks":q,"#/components":b,"#/users":A,"#/plugins":B,"#/system/notifications":j},R={};for(const[g,x]of Object.entries(U)){if(n.has(g))continue;const[W,D]=Ye[g]??["item","items"],T=K(x);T&&(R[g]={...T,label:`${T.count} ${T.count===1?W:D}`})}return{...R,...N}}let L=[];const Qe="dm:sidebar-count",et=6e4;function tt(e=[],t=null){const s=[],o=n=>{if(n&&!(t&&typeof n.url=="string"&&n.url.startsWith("#/")&&!xe(t,n.url.slice(1)))){n.url&&typeof n.countUrl=="string"&&n.countUrl&&s.push({url:n.url,countUrl:n.countUrl,text:n.text||"",countLabel:n.countLabel||"",inventory:n.inventory===!0});for(const d of[...n.children||[],...n.items||[]])o(d)}};for(const n of e??[])o(n?.item??n);return s}async function ce(e){try{const t=new Date,s=`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")}`,o=e.countUrl+(e.countUrl.includes("?")?"&":"?")+`today=${s}`;return K(await H.get(o),{fallbackLabel:e.countLabel||e.text})}catch{return null}}function de(e,t,s){ve(t,s);const o=[...e.querySelectorAll("a.sidebar-link")].filter(n=>n.dataset.url===t);if(o.length){for(const n of o){const d=n.querySelector(".sidebar-badge[data-count-for]");if(!s||!(s.count>0)&&!s.showZero)d?.remove();else{const i=document.createRange();i.selectNodeContents(n);const l=i.createContextualFragment(ie(t,s)).firstElementChild;d?d.replaceWith(l):n.querySelector(".sidebar-text")?.after(l)}}V.set(t,s),ae(e)}}const V=new Map;async function X(e,t=null){const s=t?L.filter(o=>o.url===t):L;await Promise.all(s.map(async o=>{const n=await ce(o),d=V.get(o.url);JSON.stringify(d??null)!==JSON.stringify(n)&&de(e,o.url,n)}))}function nt(e){e.dataset.liveCounts||(e.dataset.liveCounts="1",window.addEventListener(Qe,t=>{const s=t.detail||{};if(s.url)if(s.count!==void 0){const o=L.find(n=>n.url===s.url);de(e,s.url,K(s,{fallbackLabel:o?.countLabel||o?.text||""}))}else X(e,s.url)}),setInterval(()=>{!document.hidden&&document.body.contains(e)&&X(e)},et),document.addEventListener("visibilitychange",()=>{document.hidden||X(e)}),st(e))}function ue(e,t,s){const o=(i,l,u)=>{const a=document.createElement(i);return l&&(a.className=l),u!=null&&(a.textContent=String(u)),a};if(!s){e.textContent=t;return}e.appendChild(o("strong","dm-badge-pop-title",s.title||t)),(s.rows?.length||!s.items?.length)&&e.appendChild(o("p","dm-badge-pop-sub",t));const n=Array.isArray(s.rows)?s.rows.slice(0,6):[];if(n.length){const i=o("dl","dm-badge-pop-rows");for(const l of n)i.appendChild(o("dt",null,l.label)),i.appendChild(o("dd",l.tone==="danger"?"is-danger":null,l.value));e.appendChild(i)}const d=Array.isArray(s.items)?s.items.slice(0,6):[];if(d.length){const i=o("ul","dm-badge-pop-items");for(const l of d){const u=o("li",l.tone==="danger"?"is-danger":null);u.appendChild(o("span","dm-badge-pop-text",l.text)),l.meta&&u.appendChild(o("span","dm-badge-pop-meta",l.meta)),i.appendChild(u)}e.appendChild(i)}else s.empty&&e.appendChild(o("p","dm-badge-pop-empty",s.empty))}function st(e){let t=null,s=null;const o=()=>e.classList.contains("is-collapsed"),n=()=>{clearTimeout(s),t?.remove(),t=null},d=(a,r)=>{n(),s=setTimeout(()=>{t=document.createElement("div"),t.className="dm-help-pop dm-badge-pop",t.setAttribute("role","tooltip"),r(t),document.body.appendChild(t);const m=a.getBoundingClientRect(),y=t.getBoundingClientRect(),v=Math.min(m.right+10,innerWidth-y.width-8);t.style.left=`${Math.max(8,v)}px`,t.style.top=`${Math.max(8,Math.min(m.top+m.height/2-y.height/2,innerHeight-y.height-8))}px`},150)},i=a=>{const r=a?.dataset.badgeLabel;if(!r)return n();d(a,m=>ue(m,r,I.get(a.dataset.countFor)))},l=a=>{const r=a.querySelector(":scope > .sidebar-text")?.textContent.trim()||"",m=a.querySelector(":scope > .sidebar-badge[data-badge-label]:not([hidden])");d(a,y=>{const v=m&&I.get(m.dataset.countFor);if(v)return ue(y,m.dataset.badgeLabel,{...v,title:v.title||r});if(!m){y.textContent=r;return}const w=document.createElement("strong");w.className="dm-badge-pop-title",w.textContent=r;const k=document.createElement("p");k.className="dm-badge-pop-sub",k.textContent=m.dataset.badgeLabel,y.append(w,k)})},u=a=>{const r=a.closest?.("a.sidebar-link, summary");return r&&e.contains(r)?r:null};e.addEventListener("mouseover",a=>{if(o()){const m=u(a.target);m&&!m.contains(a.relatedTarget)&&l(m);return}const r=a.target.closest?.(".sidebar-badge[data-badge-label]");r&&i(r)}),e.addEventListener("mouseout",a=>{if(o()){const r=u(a.target);r&&!r.contains(a.relatedTarget)&&n();return}a.target.closest?.(".sidebar-badge[data-badge-label]")&&n()}),e.addEventListener("focusin",a=>{const r=a.target.closest?.("a, summary");if(o()&&r&&e.contains(r)&&r.querySelector(":scope > .sidebar-text"))return l(r);const m=r?.querySelector(":scope > .sidebar-badge[data-badge-label]:not([hidden])");m?i(m):n()}),e.addEventListener("focusout",n),e.addEventListener("click",n),window.addEventListener("scroll",n,!0),window.addEventListener("hashchange",n)}async function ot(e=[],t=null){if(t?.title)return t;if(!z(e,"settings"))return{title:"Domma CMS"};try{const s=await h.settings.get();return{...s?.adminBrand,title:s?.adminBrand?.title||s?.title||"Domma CMS"}}catch{return{title:"Domma CMS"}}}export async function renderAdminSidebar({mount:e,permissions:t,adminScope:s=null,brand:o=null}){const n=$(e).get(0);if(!n)return;const d=Ue(h,F()).catch(()=>{});let i,l=null,u=null,a=null,r=null,m=null;try{const c=await h.get("/sidebar/menu");i=Array.isArray(c?.items)?c.items:null,l=c?.variant||null,u=c?.position||null,a=c?.style||null,r=c?.float||null,m=c?.highlight||null}catch{i=null}(!i||!i.some(c=>c&&(!c.hidden||c.restricted)))&&(console.warn("[admin-sidebar] No admin-sidebar menu found; using fallback tree"),i=Ke.slice());let y=[];try{y=await H.get("/api/sidebar/registered-items")||[]}catch{}i=Ae(i,ee),i=ke(i,y.filter(c=>(c?.item??c)?.url!==ee)),i=Ce(i),i=Fe(i,[qe()]);const v=await Ve(t);v.length&&Xe(i,v),i=Ee(i,t,s),i=Le(i),await d;const w=Pe(i,G(F()),{hidden:Ie(F())});w&&(i=[w,...i]),De(i);const k=y.filter(c=>z(t,c?.item?.permission)),[q,b]=await Promise.all([ye({user:F(),permissions:t,adminScope:s,registered:k,tree:i,actions:{linkItems:pe,folderItems:he},fetcher:()=>Je(k,t,s)}),ot(t,o)]),A=l?` dm-admin-sidebar--${f(l)}`:"";function B(c,C="px"){if(c==null)return c;const p=String(c).trim();return/^\d+(\.\d+)?$/.test(p)?`${p}${C}`:p}let j="";if(a){const c=[];a.fontFamily&&c.push(`font-family: ${a.fontFamily}, sans-serif`),a.fontSize&&c.push(`font-size: ${B(a.fontSize)}`),a.fontWeight&&c.push(`font-weight: ${a.fontWeight}`),a.letterSpacing&&c.push(`letter-spacing: ${B(a.letterSpacing,"em")}`);const C=[];if(c.length&&C.push(`#admin-sidebar .dm-admin-sidebar, #admin-sidebar .dm-admin-sidebar .sidebar-link, #admin-sidebar .dm-admin-sidebar summary, #admin-sidebar .dm-admin-sidebar .sidebar-text { ${c.join("; ")} }`),a.iconSize){const p=B(a.iconSize);C.push(`#admin-sidebar .dm-admin-sidebar [data-icon], #admin-sidebar .dm-admin-sidebar [data-icon] svg { width: ${p} !important; height: ${p} !important; }`)}C.length&&(j=`<style data-admin-sidebar-style>${C.join(" ")}</style>`)}const N=Me(t)?Be():"",U=String(b.logo||"").trim(),R=/^(?:\/(?!\/)|https?:\/\/)/i.test(U)?U:"",x=`<div class="dm-admin-sidebar-header">${R?`<img src="${f(R)}" alt="" style="width:28px;height:28px;object-fit:contain;flex-shrink:0;">`:`<span data-icon="${f(b.icon||"layout")}"></span>`}<span class="dm-admin-sidebar-title">${f(b.title)}</span>${N}${He()}</div>`,W=i.some(c=>c&&c.type==="spacer"&&c.size==="flex")?" dm-admin-sidebar--has-flex-spacer":"",D=`${j}<nav class="dm-admin-sidebar${A}${W}">${x}${i.map(c=>le(c,q)).join("")}</nav>`,T=document.createRange();T.selectNodeContents(n);const ge=T.createContextualFragment(D);n.replaceChildren(ge),Domma.icons.scan(n),n.querySelector(".dm-admin-sidebar-arrange")?.addEventListener("click",()=>Te(n));for(const c of L)V.set(c.url,q[c.url]??null);ae(n),nt(n),n.removeAttribute("data-menu-hover"),n.removeAttribute("data-menu-active"),n.style.removeProperty("--dm-menu-highlight"),we(n,{highlight:m});const O=document.querySelector(".dashboard-wrapper");["position","top","bottom","left","right","zIndex","maxHeight","transform"].forEach(c=>{n.style[c]=""}),n.classList.remove("dm-menu-floating"),O&&(O.style.paddingLeft="",O.style.paddingRight=""),n.__dmGutter=()=>{if(u!=="floating"||!O)return;const c=r&&r.anchor||"TL",C=Number.isFinite(Number(r?.offsetX))?Number(r.offsetX):16,p=n.classList.contains("is-collapsed")?Ne:parseInt(n.style.width,10)||n.getBoundingClientRect().width||260,P=Math.round(p+C*2)+"px";c==="R"||c==="TR"||c==="BR"?O.style.paddingRight=P:O.style.paddingLeft=P},u==="floating"&&$e(n,{position:"floating",float:r||{}}),n.querySelectorAll("details").forEach(c=>{c.addEventListener("toggle",function(){const C=this.getAttribute("data-state-key");C&&S.set(C,this.open);const p=this.querySelector(":scope > .sidebar-children");if(p)if(this.open){const P=p.scrollHeight;p.style.maxHeight="0",requestAnimationFrame(()=>{p.style.maxHeight=P+"px",p.addEventListener("transitionend",function be(){p.style.maxHeight="none",p.removeEventListener("transitionend",be)})})}else{const P=p.scrollHeight;p.style.maxHeight=P+"px",requestAnimationFrame(()=>{p.style.maxHeight="0"})}})}),je(n),at(n),n.dataset.routeWired||(n.dataset.routeWired="1",M.subscribe("router:afterChange",()=>n.__dmSetActive?.()));function Y(){const c=/^#\/(dashboards|my-dashboard)\b/.test(location.hash)?"#/":location.hash||"#/";$(n).find(".sidebar-link").removeClass("active"),$(n).find(`.sidebar-link[data-url="${c}"]`).addClass("active")}Y(),n.__dmSetActive=Y}function me(){try{document.dispatchEvent(new CustomEvent("dm:sidebar-rebuild"))}catch{}}function Z(e){return`${location.origin}${location.pathname}${e}`}function _(e,t){const s=F(),o=e(G(s));if(!ze(s,o)){E.toast("Frequent could not be saved - this browser is blocking storage.",{type:"error"});return}o.length&&se(s,!1),fe(s),t&&E.toast(t,{type:"success",duration:2500}),me()}function fe(e){_e(h,e).catch(()=>E.toast("Frequent is saved in this browser only - the server could not keep it.",{type:"warning"}))}function it(e){if(!se(F(),e)){E.toast("Frequent could not be saved - this browser is blocking storage.",{type:"error"});return}fe(F()),E.toast(e?"Frequent hidden. Add a Tool to it from its right-click menu to bring it back.":"Frequent shown.",{type:"success",duration:3500}),me()}function pe(e){const t=e.dataset.url;if(!t)return[];const s=e.querySelector(".sidebar-text")?.textContent.trim()||t,o=G(F()),n=o.includes(t),d=!!e.closest("[data-frequent]"),i=o.indexOf(t),l=!n&&o.length>=te;return[{header:s},{label:"Open",icon:"arrow-right",...oe(t)&&{shortcut:Ge(oe(t))},action:()=>{location.hash=t}},{label:"Open in a new tab",icon:"external-link",action:()=>window.open(Z(t),"_blank","noopener")},{type:"divider"},n?{label:"Remove from Frequent",icon:"star",action:()=>_(u=>Re(u,t),`${s} removed from Frequent.`)}:{label:l?`Frequent is full (${te})`:"Add to Frequent",icon:"star",disabled:l,action:()=>_(u=>Oe(u,t),`${s} added to Frequent.`)},...d?[{label:"Move up",icon:"arrow-up",disabled:i<=0,action:()=>_(u=>ne(u,t,-1))},{label:"Move down",icon:"arrow-down",disabled:i<0||i>=o.length-1,action:()=>_(u=>ne(u,t,1))}]:[],{type:"divider"},{label:"Copy link",icon:"link",action:async()=>{try{await navigator.clipboard.writeText(Z(t)),E.toast("Link copied.",{type:"success",duration:2e3})}catch{E.toast(Z(t),{type:"info",duration:8e3})}}}]}function he(e,t,s={}){const o=e.closest("details, [data-frequent]"),n=s.isOpen||(()=>!!o?.open),d=s.setOpen||(u=>{o&&(o.open=u)}),i=e.querySelector(".sidebar-text")?.textContent.trim()||"Folder",l=s.setAll||(u=>t.querySelectorAll("details").forEach(a=>{a.open!==u&&(a.open=u)}));return[{header:i},{label:n()?"Close":"Open",icon:n()?"chevron-up":"chevron-down",action:()=>d(!n())},...s.singleBranch?[]:[{label:"Open every folder",icon:"chevrons-down",action:()=>l(!0)}],{label:s.singleBranch?"Close all menus":"Close every folder",icon:"chevrons-up",action:()=>l(!1)},...o?.hasAttribute("data-frequent-empty")?[{type:"divider"},{label:"Hide Frequent until I add a Tool",icon:"eye-off",action:()=>it(!0)}]:o?.hasAttribute("data-frequent")?[{type:"divider"},{label:"Clear Frequent",icon:"x",action:()=>_(()=>[],"Frequent cleared.")}]:[]]}function at(e){e.dataset.ctxWired||typeof E>"u"||!E.contextMenu||(e.dataset.ctxWired="1",E.contextMenu(e,{match:"a.sidebar-link, details > summary",inherit:!1,density:"compact",items:t=>t.matches("summary")?he(t,e):pe(t)}))}
@@ -1 +1 @@
1
- export const TAB_FIELDS={general:["title","tagline","siteUrl","adminHome","spacerSize","bodyClass"],branding:["brandText","brandLogo","brandIcon","brandUrl","adminBrandTitle","adminBrandLogo","adminBrandIcon"],favicon:["favicon"],seo:["seoTitle","seoSeparator","seoDescription"],footer:["footerCopyright","footerLayout","footerBlurb","footerBlocks","footerMotionToggle","footerMotionDefault","footerMotionControl","footerClass","footerSocialClass","socialTwitter","socialFacebook","socialInstagram","socialLinkedin","socialGithub","socialYoutube"],email:["smtpHost","smtpPort","smtpUser","smtpPass","smtpSecure","smtpInsecureTLS","smtpFromAddress","smtpFromName"],backToTop:["bttEnabled","bttSmooth","bttLabel","bttThreshold","bttPosition","bttOffset","bttBottomOffset"],cookies:["ccEnabled","ccMessage","ccAcceptAll","ccRejectAll","ccCustomize","ccSavePrefs","ccPrivacyText","ccPrivacyUrl","ccCookieText","ccCookieUrl","ccPosition","ccLayout","ccTheme","ccShowFunctional","ccShowAnalytics","ccShowMarketing","ccVersion"],breadcrumbs:["bcEnabled","bcHomeLabel","bcPosition","bcOffsetX","bcOffsetY"],css:["css"]},SECRET_FIELDS=["smtpPass"],BREADCRUMB_POSITIONS=["TL","TR","BL","BR"];export function footerBlockNames(o){return[...new Set(String(o??"").split(/[\s,]+/).map(r=>r.trim().toLowerCase()).filter(Boolean))]}export const FOOTER_LAYOUTS=["auto","columns","row"];const t=(o,r="")=>o==null?r:String(o),i=(o,r)=>{const c=Number.parseInt(o,10);return Number.isFinite(c)?c:r};export function homeValue(o){return/^\/[A-Za-z0-9\-_/]*$/.test(o||"")&&String(o).replace(/\/+$/,"")||"/"}export function formFromSettings(o={},r=""){const c=o.backToTop||{},e=o.cookieConsent||{},s=o.breadcrumbs||{};return{title:t(o.title),tagline:t(o.tagline),siteUrl:t(o.baseUrl),adminHome:homeValue(o.adminHome),spacerSize:t(o.layoutOptions?.spacerSize??40),bodyClass:t(o.bodyClass),brandText:t(o.brand?.text),brandLogo:t(o.brand?.logo),brandIcon:t(o.brand?.icon),brandUrl:t(o.brand?.url,"/"),favicon:t(o.favicon),adminBrandTitle:t(o.adminBrand?.title),adminBrandLogo:t(o.adminBrand?.logo),adminBrandIcon:t(o.adminBrand?.icon),seoTitle:t(o.seo?.defaultTitle),seoSeparator:t(o.seo?.titleSeparator," | "),seoDescription:t(o.seo?.defaultDescription),footerCopyright:t(o.footer?.copyright),footerLayout:FOOTER_LAYOUTS.includes(o.footer?.layout)?o.footer.layout:"auto",footerBlurb:t(o.footer?.blurb),footerBlocks:Array.isArray(o.footer?.blocks)?o.footer.blocks.filter(a=>typeof a=="string").join(", "):"",footerMotionToggle:o.footer?.showMotionToggle!==!1,footerMotionDefault:["off","on"].includes(o.footer?.motionDefault)?o.footer.motionDefault:"system",footerMotionControl:o.footer?.motionControl==="checkbox"?"checkbox":"switch",footerClass:t(o.footer?.class),footerSocialClass:t(o.footer?.socialClass),socialTwitter:t(o.social?.twitter),socialFacebook:t(o.social?.facebook),socialInstagram:t(o.social?.instagram),socialLinkedin:t(o.social?.linkedin),socialGithub:t(o.social?.github),socialYoutube:t(o.social?.youtube),smtpHost:t(o.smtp?.host),smtpPort:t(o.smtp?.port||587),smtpUser:t(o.smtp?.user),smtpPass:"",smtpSecure:o.smtp?.secure===!0,smtpInsecureTLS:o.smtp?.allowInsecureTLS===!0,smtpFromAddress:t(o.smtp?.fromAddress),smtpFromName:t(o.smtp?.fromName),bttEnabled:c.enabled!==!1,bttSmooth:c.smooth!==!1,bttLabel:t(c.label),bttThreshold:t(c.scrollThreshold??300),bttPosition:t(c.position,"bottom-right"),bttOffset:t(c.offset??32),bttBottomOffset:t(c.bottomOffset??c.offset??32),ccEnabled:e.enabled!==!1,ccMessage:t(e.message),ccAcceptAll:t(e.acceptAllText,"Accept All"),ccRejectAll:t(e.rejectAllText,"Reject All"),ccCustomize:t(e.customizeText,"Customize"),ccSavePrefs:t(e.savePreferencesText,"Save Preferences"),ccPrivacyText:t(e.privacyPolicyText,"Privacy Policy"),ccPrivacyUrl:t(e.privacyPolicyUrl),ccCookieText:t(e.cookiePolicyText,"Cookie Policy"),ccCookieUrl:t(e.cookiePolicyUrl),ccPosition:t(e.position,"bottom"),ccLayout:t(e.layout,"bar"),ccTheme:t(e.theme,"dark"),ccShowFunctional:e.showFunctional!==!1,ccShowAnalytics:e.showAnalytics!==!1,ccShowMarketing:e.showMarketing!==!1,ccVersion:t(e.consentVersion,"1.0"),bcEnabled:s.enabled===!0,bcHomeLabel:t(s.homeLabel,"Home"),bcPosition:BREADCRUMB_POSITIONS.includes(s.position)?s.position:"TL",bcOffsetX:t(s.offsetX??8),bcOffsetY:t(s.offsetY??8),css:t(r)}}export function payloadFromForm(o,r={},{adminHomeReady:c=!0}={}){const e=s=>t(s).trim();return{title:e(o.title),tagline:e(o.tagline),baseUrl:e(o.siteUrl).replace(/\/+$/,""),...c&&{adminHome:e(o.adminHome)||"/"},layoutOptions:{spacerSize:i(o.spacerSize,40)||40},bodyClass:e(o.bodyClass),brand:{...r.brand,text:e(o.brandText),logo:e(o.brandLogo),icon:e(o.brandIcon),url:e(o.brandUrl)||"/"},favicon:e(o.favicon),adminBrand:{...r.adminBrand,title:e(o.adminBrandTitle),logo:e(o.adminBrandLogo),icon:e(o.adminBrandIcon)},seo:{defaultTitle:e(o.seoTitle),titleSeparator:t(o.seoSeparator)||" | ",defaultDescription:e(o.seoDescription)},footer:{copyright:e(o.footerCopyright),layout:FOOTER_LAYOUTS.includes(o.footerLayout)?o.footerLayout:"auto",blurb:e(o.footerBlurb),blocks:footerBlockNames(o.footerBlocks),showMotionToggle:o.footerMotionToggle===!0,links:r.footer?.links||[],motionDefault:["off","on"].includes(o.footerMotionDefault)?o.footerMotionDefault:"system",motionControl:o.footerMotionControl==="checkbox"?"checkbox":"switch",class:e(o.footerClass),socialClass:e(o.footerSocialClass)},social:{twitter:e(o.socialTwitter),facebook:e(o.socialFacebook),instagram:e(o.socialInstagram),linkedin:e(o.socialLinkedin),github:e(o.socialGithub),youtube:e(o.socialYoutube)},smtp:{host:e(o.smtpHost),port:i(o.smtpPort,587)||587,user:e(o.smtpUser),pass:t(o.smtpPass),secure:o.smtpSecure===!0,allowInsecureTLS:o.smtpInsecureTLS===!0,fromAddress:e(o.smtpFromAddress),fromName:e(o.smtpFromName)},backToTop:{enabled:o.bttEnabled===!0,scrollThreshold:i(o.bttThreshold,300),position:t(o.bttPosition)||"bottom-right",offset:i(o.bttOffset,32),bottomOffset:i(o.bttBottomOffset,32),label:e(o.bttLabel),smooth:o.bttSmooth===!0},cookieConsent:{enabled:o.ccEnabled===!0,message:e(o.ccMessage),acceptAllText:e(o.ccAcceptAll),rejectAllText:e(o.ccRejectAll),customizeText:e(o.ccCustomize),savePreferencesText:e(o.ccSavePrefs),privacyPolicyText:e(o.ccPrivacyText),privacyPolicyUrl:e(o.ccPrivacyUrl),cookiePolicyText:e(o.ccCookieText),cookiePolicyUrl:e(o.ccCookieUrl),position:t(o.ccPosition)||"bottom",layout:t(o.ccLayout)||"bar",theme:t(o.ccTheme)||"dark",showFunctional:o.ccShowFunctional===!0,showAnalytics:o.ccShowAnalytics===!0,showMarketing:o.ccShowMarketing===!0,consentVersion:e(o.ccVersion)||"1.0"},breadcrumbs:{enabled:o.bcEnabled===!0,homeLabel:e(o.bcHomeLabel)||"Home",position:BREADCRUMB_POSITIONS.includes(o.bcPosition)?o.bcPosition:"TL",offsetX:i(o.bcOffsetX,8),offsetY:i(o.bcOffsetY,8)}}}export function siteUrlError(o){const r=t(o).trim().replace(/\/+$/,"");return r?/^https?:\/\//i.test(r)?/^https?:\/\/([a-z0-9.\-]+|\[[0-9a-f:.]+\])(:\d{1,5})?$/i.test(r)?"":"Just the address, like https://example.com - no page path after it.":"Start with https:// (or http://).":""}const n=o=>typeof o=="boolean"?o:t(o);export function snapshot(o){return JSON.stringify(Object.keys(o).sort().map(r=>[r,n(o[r])]))}export function changedTabs(o,r){const c=[];for(const[e,s]of Object.entries(TAB_FIELDS))s.some(a=>n(o[a])!==n(r[a]))&&c.push(e);return c}export function draftOf(o){return Object.fromEntries(Object.entries(o).filter(([r])=>!SECRET_FIELDS.includes(r)))}export function settingsProblems(o){const r=[];return t(o.smtpHost).trim()?t(o.smtpFromAddress).trim()||r.push({tone:"warn",tab:"email",text:"No From address - mail has no sender and many servers refuse it."}):r.push({tone:"danger",tab:"email",text:"No SMTP host - mail goes to a throwaway test inbox and reaches no one (password resets, form notifications)."}),o.ccEnabled===!0&&!t(o.ccPrivacyUrl).trim()&&r.push({tone:"warn",tab:"cookies",text:"The cookie banner is on but links to no privacy policy."}),r}export function describeCacheKey(o){const r=/^page:(.*?):m\d+:role([^:]*):/.exec(String(o||""));return r?{path:r[1]||"/",role:r[2]||"anon",page:!0}:{path:String(o||""),role:"",page:!1}}export function expiresIn(o,r=Date.now()){if(o==null)return"no expiry";const c=o-r;return c<=0?"expired":c<6e4?`${Math.round(c/1e3)}s`:c<36e5?`${Math.round(c/6e4)}m`:`${Math.round(c/36e5)}h`}
1
+ export const TAB_FIELDS={general:["title","tagline","siteUrl","adminHome","spacerSize","bodyClass"],branding:["brandText","brandLogo","brandIcon","brandUrl","adminBrandTitle","adminBrandLogo","adminBrandIcon"],favicon:["favicon"],seo:["seoTitle","seoSeparator","seoDescription"],footer:["footerCopyright","footerLayout","footerBlurb","footerBlocks","footerMotionToggle","footerMotionDefault","footerMotionControl","footerClass","footerSocialClass","socialTwitter","socialFacebook","socialInstagram","socialLinkedin","socialGithub","socialYoutube"],email:["smtpHost","smtpPort","smtpUser","smtpPass","smtpSecure","smtpInsecureTLS","smtpFromAddress","smtpFromName"],pageNavigation:["bttEnabled","bttSmooth","bttLabel","bttThreshold","bttPosition","bttOffset","bttBottomOffset","gtbEnabled","gtbSmooth","gtbLabel","gtbThreshold","gtbPosition","gtbOffset","gtbBottomOffset"],cookies:["ccEnabled","ccMessage","ccAcceptAll","ccRejectAll","ccCustomize","ccSavePrefs","ccPrivacyText","ccPrivacyUrl","ccCookieText","ccCookieUrl","ccPosition","ccLayout","ccTheme","ccShowFunctional","ccShowAnalytics","ccShowMarketing","ccVersion"],breadcrumbs:["bcEnabled","bcHomeLabel","bcPosition","bcOffsetX","bcOffsetY"]},SECRET_FIELDS=["smtpPass"],BREADCRUMB_POSITIONS=["TL","TR","BL","BR"];export function footerBlockNames(o){return[...new Set(String(o??"").split(/[\s,]+/).map(r=>r.trim().toLowerCase()).filter(Boolean))]}export const FOOTER_LAYOUTS=["auto","columns","row"];const t=(o,r="")=>o==null?r:String(o),c=(o,r)=>{const s=Number.parseInt(o,10);return Number.isFinite(s)?s:r};export function homeValue(o){return/^\/[A-Za-z0-9\-_/]*$/.test(o||"")&&String(o).replace(/\/+$/,"")||"/"}export function formFromSettings(o={}){const r=o.backToTop||{},s=o.goToBottom||{},e=o.cookieConsent||{},i=o.breadcrumbs||{};return{title:t(o.title),tagline:t(o.tagline),siteUrl:t(o.baseUrl),adminHome:homeValue(o.adminHome),spacerSize:t(o.layoutOptions?.spacerSize??40),bodyClass:t(o.bodyClass),brandText:t(o.brand?.text),brandLogo:t(o.brand?.logo),brandIcon:t(o.brand?.icon),brandUrl:t(o.brand?.url,"/"),favicon:t(o.favicon),adminBrandTitle:t(o.adminBrand?.title),adminBrandLogo:t(o.adminBrand?.logo),adminBrandIcon:t(o.adminBrand?.icon),seoTitle:t(o.seo?.defaultTitle),seoSeparator:t(o.seo?.titleSeparator," | "),seoDescription:t(o.seo?.defaultDescription),footerCopyright:t(o.footer?.copyright),footerLayout:FOOTER_LAYOUTS.includes(o.footer?.layout)?o.footer.layout:"auto",footerBlurb:t(o.footer?.blurb),footerBlocks:Array.isArray(o.footer?.blocks)?o.footer.blocks.filter(a=>typeof a=="string").join(", "):"",footerMotionToggle:o.footer?.showMotionToggle!==!1,footerMotionDefault:["off","on"].includes(o.footer?.motionDefault)?o.footer.motionDefault:"system",footerMotionControl:o.footer?.motionControl==="checkbox"?"checkbox":"switch",footerClass:t(o.footer?.class),footerSocialClass:t(o.footer?.socialClass),socialTwitter:t(o.social?.twitter),socialFacebook:t(o.social?.facebook),socialInstagram:t(o.social?.instagram),socialLinkedin:t(o.social?.linkedin),socialGithub:t(o.social?.github),socialYoutube:t(o.social?.youtube),smtpHost:t(o.smtp?.host),smtpPort:t(o.smtp?.port||587),smtpUser:t(o.smtp?.user),smtpPass:"",smtpSecure:o.smtp?.secure===!0,smtpInsecureTLS:o.smtp?.allowInsecureTLS===!0,smtpFromAddress:t(o.smtp?.fromAddress),smtpFromName:t(o.smtp?.fromName),bttEnabled:r.enabled!==!1,bttSmooth:r.smooth!==!1,bttLabel:t(r.label),bttThreshold:t(r.scrollThreshold??300),bttPosition:t(r.position,"bottom-right"),bttOffset:t(r.offset??32),bttBottomOffset:t(r.bottomOffset??r.offset??32),gtbEnabled:s.enabled===!0,gtbSmooth:s.smooth!==!1,gtbLabel:t(s.label),gtbThreshold:t(s.scrollThreshold??300),gtbPosition:t(s.position,"bottom-right"),gtbOffset:t(s.offset??32),gtbBottomOffset:t(s.bottomOffset??s.offset??32),ccEnabled:e.enabled!==!1,ccMessage:t(e.message),ccAcceptAll:t(e.acceptAllText,"Accept All"),ccRejectAll:t(e.rejectAllText,"Reject All"),ccCustomize:t(e.customizeText,"Customize"),ccSavePrefs:t(e.savePreferencesText,"Save Preferences"),ccPrivacyText:t(e.privacyPolicyText,"Privacy Policy"),ccPrivacyUrl:t(e.privacyPolicyUrl),ccCookieText:t(e.cookiePolicyText,"Cookie Policy"),ccCookieUrl:t(e.cookiePolicyUrl),ccPosition:t(e.position,"bottom"),ccLayout:t(e.layout,"bar"),ccTheme:t(e.theme,"dark"),ccShowFunctional:e.showFunctional!==!1,ccShowAnalytics:e.showAnalytics!==!1,ccShowMarketing:e.showMarketing!==!1,ccVersion:t(e.consentVersion,"1.0"),bcEnabled:i.enabled===!0,bcHomeLabel:t(i.homeLabel,"Home"),bcPosition:BREADCRUMB_POSITIONS.includes(i.position)?i.position:"TL",bcOffsetX:t(i.offsetX??8),bcOffsetY:t(i.offsetY??8)}}export function payloadFromForm(o,r={},{adminHomeReady:s=!0}={}){const e=i=>t(i).trim();return{title:e(o.title),tagline:e(o.tagline),baseUrl:e(o.siteUrl).replace(/\/+$/,""),...s&&{adminHome:e(o.adminHome)||"/"},layoutOptions:{spacerSize:c(o.spacerSize,40)||40},bodyClass:e(o.bodyClass),brand:{...r.brand,text:e(o.brandText),logo:e(o.brandLogo),icon:e(o.brandIcon),url:e(o.brandUrl)||"/"},favicon:e(o.favicon),adminBrand:{...r.adminBrand,title:e(o.adminBrandTitle),logo:e(o.adminBrandLogo),icon:e(o.adminBrandIcon)},seo:{defaultTitle:e(o.seoTitle),titleSeparator:t(o.seoSeparator)||" | ",defaultDescription:e(o.seoDescription)},footer:{copyright:e(o.footerCopyright),layout:FOOTER_LAYOUTS.includes(o.footerLayout)?o.footerLayout:"auto",blurb:e(o.footerBlurb),blocks:footerBlockNames(o.footerBlocks),showMotionToggle:o.footerMotionToggle===!0,links:r.footer?.links||[],motionDefault:["off","on"].includes(o.footerMotionDefault)?o.footerMotionDefault:"system",motionControl:o.footerMotionControl==="checkbox"?"checkbox":"switch",class:e(o.footerClass),socialClass:e(o.footerSocialClass)},social:{twitter:e(o.socialTwitter),facebook:e(o.socialFacebook),instagram:e(o.socialInstagram),linkedin:e(o.socialLinkedin),github:e(o.socialGithub),youtube:e(o.socialYoutube)},smtp:{host:e(o.smtpHost),port:c(o.smtpPort,587)||587,user:e(o.smtpUser),pass:t(o.smtpPass),secure:o.smtpSecure===!0,allowInsecureTLS:o.smtpInsecureTLS===!0,fromAddress:e(o.smtpFromAddress),fromName:e(o.smtpFromName)},backToTop:{enabled:o.bttEnabled===!0,scrollThreshold:c(o.bttThreshold,300),position:t(o.bttPosition)||"bottom-right",offset:c(o.bttOffset,32),bottomOffset:c(o.bttBottomOffset,32),label:e(o.bttLabel),smooth:o.bttSmooth===!0},goToBottom:{enabled:o.gtbEnabled===!0,scrollThreshold:c(o.gtbThreshold,300),position:t(o.gtbPosition)||"bottom-right",offset:c(o.gtbOffset,32),bottomOffset:c(o.gtbBottomOffset,32),label:e(o.gtbLabel),smooth:o.gtbSmooth===!0},cookieConsent:{enabled:o.ccEnabled===!0,message:e(o.ccMessage),acceptAllText:e(o.ccAcceptAll),rejectAllText:e(o.ccRejectAll),customizeText:e(o.ccCustomize),savePreferencesText:e(o.ccSavePrefs),privacyPolicyText:e(o.ccPrivacyText),privacyPolicyUrl:e(o.ccPrivacyUrl),cookiePolicyText:e(o.ccCookieText),cookiePolicyUrl:e(o.ccCookieUrl),position:t(o.ccPosition)||"bottom",layout:t(o.ccLayout)||"bar",theme:t(o.ccTheme)||"dark",showFunctional:o.ccShowFunctional===!0,showAnalytics:o.ccShowAnalytics===!0,showMarketing:o.ccShowMarketing===!0,consentVersion:e(o.ccVersion)||"1.0"},breadcrumbs:{enabled:o.bcEnabled===!0,homeLabel:e(o.bcHomeLabel)||"Home",position:BREADCRUMB_POSITIONS.includes(o.bcPosition)?o.bcPosition:"TL",offsetX:c(o.bcOffsetX,8),offsetY:c(o.bcOffsetY,8)}}}export function siteUrlError(o){const r=t(o).trim().replace(/\/+$/,"");return r?/^https?:\/\//i.test(r)?/^https?:\/\/([a-z0-9.\-]+|\[[0-9a-f:.]+\])(:\d{1,5})?$/i.test(r)?"":"Just the address, like https://example.com - no page path after it.":"Start with https:// (or http://).":""}const n=o=>typeof o=="boolean"?o:t(o);export function snapshot(o){return JSON.stringify(Object.keys(o).sort().map(r=>[r,n(o[r])]))}export function changedTabs(o,r){const s=[];for(const[e,i]of Object.entries(TAB_FIELDS))i.some(a=>n(o[a])!==n(r[a]))&&s.push(e);return s}export function draftOf(o){return Object.fromEntries(Object.entries(o).filter(([r])=>!SECRET_FIELDS.includes(r)))}export function settingsProblems(o){const r=[];return t(o.smtpHost).trim()?t(o.smtpFromAddress).trim()||r.push({tone:"warn",tab:"email",text:"No From address - mail has no sender and many servers refuse it."}):r.push({tone:"danger",tab:"email",text:"No SMTP host - mail goes to a throwaway test inbox and reaches no one (password resets, form notifications)."}),o.ccEnabled===!0&&!t(o.ccPrivacyUrl).trim()&&r.push({tone:"warn",tab:"cookies",text:"The cookie banner is on but links to no privacy policy."}),r}export function describeCacheKey(o){const r=/^page:(.*?):m\d+:role([^:]*):/.exec(String(o||""));return r?{path:r[1]||"/",role:r[2]||"anon",page:!0}:{path:String(o||""),role:"",page:!1}}export function expiresIn(o,r=Date.now()){if(o==null)return"no expiry";const s=o-r;return s<=0?"expired":s<6e4?`${Math.round(s/1e3)}s`:s<36e5?`${Math.round(s/6e4)}m`:`${Math.round(s/36e5)}h`}
@@ -0,0 +1 @@
1
+ let s={};export function renderFrameworkVersions(r){r&&(s=r);for(const[e,i,o]of[["topbar-reactive-version","Reactive",s.reactive],["topbar-js-version","JS",globalThis.Domma?.version||s.js]]){const n=document.getElementById(e);n&&(n.textContent=o||"",n.parentElement.hidden=!o,n.hidden=!o)}}export function sidebarPreferenceKey(r){return"sidebar.visible."+(r?.id||"anonymous")}export function wireAccountMenu(r){c("topbar-account"),c("topbar-versions-menu");const e=document.getElementById("topbar-show-sidebar");if(!e||e.dataset.wired)return;e.dataset.wired="1";const i=sidebarPreferenceKey(r);let o=!0;try{o=S.get(i)!==!1}catch{}const n=a=>{!a&&document.body.classList.contains("dm-sidebar-open")&&document.getElementById("topbar-sidebar-toggle")?.click(),document.body.classList.toggle("dm-sidebar-hidden",!a),e.checked=a};n(o),e.addEventListener("change",()=>{n(e.checked);try{S.set(i,e.checked)}catch{}})}const d=new Map;function c(r){const e=document.getElementById(r);if(!e||e.dataset.wired)return;e.dataset.wired="1";const i=e.querySelector("button"),o=e.querySelector(".topbar-account-menu"),n=t=>{t&&document.dispatchEvent(new CustomEvent("dm:topbar-menu-open",{detail:{owner:e}})),o.hidden=!t,i.setAttribute("aria-expanded",String(t))};i.addEventListener("click",()=>n(o.hidden)),i.addEventListener("keydown",t=>{t.key==="ArrowDown"&&(t.preventDefault(),n(!0),o.querySelector("a, input")?.focus())}),e.addEventListener("click",t=>{t.target.closest("a")&&n(!1)}),d.get(r)?.abort();const a=new AbortController;d.set(r,a),document.addEventListener("click",t=>{e.contains(t.target)||n(!1)},{signal:a.signal}),document.addEventListener("dm:topbar-menu-open",t=>{t.detail.owner!==e&&n(!1)},{signal:a.signal}),document.addEventListener("keydown",t=>{!t.defaultPrevented&&t.key==="Escape"&&!o.hidden&&(n(!1),i.focus(),t.preventDefault())},{signal:a.signal}),window.addEventListener("hashchange",()=>n(!1),{signal:a.signal})}
@@ -0,0 +1 @@
1
+ export function navigationItems(f){return(Array.isArray(f)?f:[]).flatMap(a=>{if(!a||a.hidden||a.restricted||["separator","spacer","theme-switcher"].includes(a.type))return[];const u=navigationItems(a.items),m=typeof a.url=="string"&&/^#\//.test(a.url)?a.url:null;return u.length||m||a.frequent?[{text:String(a.text||""),url:m,items:u,...a.key&&{key:a.key},...a.icon&&{icon:a.icon},...a.frequent&&{frequent:!0,empty:!u.length}}]:[]})}export function navigationBadge(f,a){const u=f.url&&a[f.url];if(u&&(u.count>0||u.showZero))return{count:u.count,show:!0,label:u.label||`${u.count} items`,tone:u.tone||"info"};let m=0,g=!1;const s=new Set,h=b=>{const l=b.url&&a[b.url];l?.aggregate&&l.count>0&&!s.has(b.url)&&(s.add(b.url),m+=l.count,g||(g=l.tone==="danger")),b.items.forEach(h)};return f.items.forEach(h),{count:m,show:m>0,label:`${m} across ${f.text}`,tone:g?"danger":"info"}}let y;export function updateTopbarCounts(f,{replace:a=!1}={}){y&&(y.value=a?f:{...y.peek(),...f})}let L,q,O,P,C,B,z;export function renderTopbarNavigation(f,{linkItems:a,folderItems:u,counts:m={}}={}){const g=document.getElementById("admin-topbar");if(!g)return;let s=document.getElementById("topbar-navigation");s||(s=document.createElement("nav"),s.id="topbar-navigation",s.className="topbar-navigation",s.setAttribute("aria-label","Admin sections"),g.insertBefore(s,g.querySelector(".topbar-user"))),L?.abort(),O?.dispose(),C?.dispose?.(),B?.dispose?.(),z?.(),P?.destroy?.(),L=new AbortController;const{signal:h}=L;s.replaceChildren();const b=new Map,l=M.observable([]);y=M.observable(m);const A=new Map;C=M.computed(()=>Object.fromEntries(l.value.map(e=>[e,!0])));const v=({focus:e=!1}={})=>{const t=b.get(l.peek()[0]);l.value=[],e&&t?.button.focus()},$=(e,t,o)=>{const n=document.createElement("span");n.setAttribute("data-icon",t.icon||(o?"folder":"file")),e.append(n);const d=document.createElement("span");d.className="sidebar-text",d.textContent=t.text,e.append(d);const i="b"+A.size;A.set(i,t);const r=document.createElement("span");if(r.className="topbar-nav-count",r.setAttribute("data-count-for",t.url||"folder:"+t.text),r.setAttribute("data-bind-text",`badges.value.${i}.count`),r.setAttribute("data-bind-hidden",`!badges.value.${i}.show`),r.setAttribute("data-bind-title",`badges.value.${i}.label`),r.setAttribute("data-bind-aria-label",`badges.value.${i}.label`),r.setAttribute("data-bind-class",`badges.value.${i}.tone === 'danger' ? 'is-danger' : ''`),e.append(r),o){const p=document.createElement("span");p.className="topbar-nav-chevron",p.setAttribute("data-icon",o),e.append(p)}},N=e=>{if(!l.peek().includes(e.id))return;const t=e.button.getBoundingClientRect(),o=e.panel.offsetWidth;let n=t.left,d=g.getBoundingClientRect().bottom;if(e.parents.length){const i=b.get(e.parents.at(-1)).panel.getBoundingClientRect();n=i.right-2,n+o>innerWidth-8&&(n=i.left-o+2),d=Math.min(t.top,innerHeight-Math.min(e.panel.scrollHeight,240)-12)}d=Math.max(g.getBoundingClientRect().bottom,d),e.panel.style.left=Math.max(8,Math.min(n,innerWidth-o-8))+"px",e.panel.style.top=d+"px",e.panel.style.maxHeight=Math.max(100,innerHeight-d-12)+"px"},w=(e,{focus:t=!1}={})=>{document.dispatchEvent(new CustomEvent("dm:topbar-menu-open",{detail:{owner:s}})),l.value=[...e.parents,e.id],requestAnimationFrame(()=>{N(e),t&&e.panel.querySelector("a, button")?.focus()})},R=(e,t,o)=>{const n=document.createElement("a");n.className="topbar-nav-link",n.href=t.url,n.dataset.url=t.url,$(n,t),n.addEventListener("pointerenter",()=>{l.peek().length&&(l.value=o)}),e.append(n)},D=(e,t,o=[])=>{for(const n of t){if(!n.items.length&&!n.frequent){R(e,n,o);continue}const d=document.createElement("div");d.className="topbar-nav-group",d.dataset.menuKey=n.key||n.text.trim().toLowerCase().replace(/\s+/g,"-"),n.frequent&&(d.setAttribute("data-frequent",""),n.empty&&d.setAttribute("data-frequent-empty",""));const i=document.createElement("button");i.type="button",i.className="topbar-nav-button",$(i,n,o.length?"chevron-right":"chevron-down");const r=document.createElement("div");r.className="topbar-nav-panel";const p="n"+b.size;r.id="topbar-nav-panel-"+p,r.setAttribute("aria-label",n.text),r.setAttribute("data-bind-hidden",`!open.value.${p}`),r.hidden=!0,i.setAttribute("aria-controls",r.id),i.setAttribute("data-bind-aria-expanded",`open.value.${p} ? 'true' : 'false'`),i.setAttribute("data-on-click",`toggle('${p}')`);const x={id:p,button:i,panel:r,parents:o};if(b.set(p,x),i.dataset.entry=p,n.url&&R(r,n,[...o,p]),D(r,n.items,[...o,p]),n.empty){const c=document.createElement("p");c.className="topbar-nav-empty",c.textContent="Right-click a tool to add it to Frequent.",r.append(c)}i.addEventListener("pointerenter",c=>{c.pointerType==="mouse"&&o.length&&w(x)}),i.addEventListener("keydown",c=>{(c.key==="ArrowDown"||o.length&&c.key==="ArrowRight")&&(c.preventDefault(),w(x,{focus:!0}))}),r.addEventListener("keydown",c=>{if(!c.defaultPrevented){if(c.key==="ArrowLeft"||c.key==="Escape")c.preventDefault(),c.stopPropagation(),l.value=o,i.focus();else if(c.key==="ArrowDown"||c.key==="ArrowUp"){const k=[...r.querySelectorAll(":scope > a, :scope > .topbar-nav-group > button")],S=k.indexOf(document.activeElement);S>=0&&(c.preventDefault(),c.stopPropagation(),k[(S+(c.key==="ArrowDown"?1:k.length-1))%k.length]?.focus())}}}),r.addEventListener("scroll",()=>{l.value=[...o,p]}),d.append(i,r),e.append(d)}};D(s,navigationItems(f)),s.hidden=!s.children.length,B=M.computed(()=>Object.fromEntries([...A].map(([e,t])=>[e,navigationBadge(t,y.value)]))),O=M.applyBindings({open:C,badges:B},s,{methods:{toggle:e=>{const t=b.get(e);!t.parents.length&&l.peek().includes(e)?l.value=t.parents:w(t)}}}),z=M.effect(()=>{y.value,requestAnimationFrame(()=>l.peek().forEach(e=>N(b.get(e))))}),Domma.icons.scan(s),E.contextMenu&&a&&u&&(P=E.contextMenu(s,{match:"a.topbar-nav-link, button.topbar-nav-button",inherit:!1,density:"compact",items:e=>{if(e.matches("a"))return a(e);const t=b.get(e.dataset.entry);return u(e,s,{singleBranch:!0,isOpen:()=>l.peek().includes(t.id),setOpen:o=>o?w(t):l.value=t.parents,setAll:o=>o?w(t):v()})}})),s.addEventListener("click",e=>{e.target.closest("a")&&v()},{signal:h}),document.addEventListener("click",e=>{s.contains(e.target)||v()},{signal:h}),document.addEventListener("dm:topbar-menu-open",e=>{e.detail.owner!==s&&v()},{signal:h}),document.addEventListener("keydown",e=>{!e.defaultPrevented&&e.key==="Escape"&&l.peek().length&&(v({focus:!0}),e.preventDefault())},{signal:h}),window.addEventListener("hashchange",()=>v(),{signal:h}),window.addEventListener("resize",()=>v(),{signal:h}),s.addEventListener("scroll",()=>v(),{signal:h}),q?.disconnect(),q=new ResizeObserver(()=>{const e=g.getBoundingClientRect().height;e&&document.documentElement.style.setProperty("--admin-topbar-height",e+"px")}),q.observe(g)}
@@ -0,0 +1 @@
1
+ export function topbarProjectSlug(n){const[o,t=""]=String(n||"").replace(/^#/,"").split("?"),e=new URLSearchParams(t).get("project");if(e)return e;const r=o.match(/^\/projects\/(?:edit\/)?([^/]+)(?:\/|$)/);if(!r||r[1]==="new")return null;try{return decodeURIComponent(r[1])}catch{return null}}let a=0;export async function refreshTopbarProject(n){const o=++a,t=document.getElementById("topbar-project");if(!t)return;t.hidden=!0;const e=topbarProjectSlug(location.hash);if(e)try{const r=await n.projects.get(e);if(o!==a||!r)return;const c=r.name||e;t.querySelector("#topbar-project-name").textContent=c,t.href="#/projects/"+encodeURIComponent(e),t.title=`Current project: ${c}`,t.setAttribute("aria-label",`Current project: ${c}`),t.hidden=!1}catch{}}
@@ -1 +1 @@
1
- const r="x-domma-cms-version";export function noticeFor(n,e){const t=typeof e=="string"?e.trim():"";return t?n.baseline?t===n.baseline||t===n.dismissed?{baseline:n.baseline,show:null}:{baseline:n.baseline,show:t}:{baseline:t,show:null}:{baseline:n.baseline,show:null}}const i={baseline:null,dismissed:null,showing:null};let a=!1,o=null;function c(n){if(!o){o=document.createElement("div"),o.className="dm-update-notice",o.setAttribute("role","status");const e=document.createElement("span");e.className="dm-update-notice__text";const t=document.createElement("button");t.type="button",t.className="btn btn-sm btn-primary",t.textContent="Reload",t.addEventListener("click",()=>location.reload());const s=document.createElement("button");s.type="button",s.className="btn btn-sm btn-ghost",s.textContent="Later",s.addEventListener("click",()=>{i.dismissed=i.showing,i.showing=null,o.hidden=!0}),o.append(e,t,s),document.body.appendChild(o)}o.querySelector(".dm-update-notice__text").textContent=`Domma CMS has been updated to ${n}. This tab is still running ${i.baseline} - save what you are working on, then reload so new settings are saved properly.`,o.hidden=!1}function d(n){try{const e=noticeFor(i,n.headers.get(r));i.baseline=e.baseline,e.show&&e.show!==i.showing&&(i.showing=e.show,c(e.show))}catch{}}export function installUpdateNotice(){if(a||typeof window>"u"||typeof window.fetch!="function")return;a=!0;const n=window.fetch;window.fetch=function(e,t){const s=n.call(this,e,t),l=typeof e=="string"?e:e&&e.url||"";return(l.startsWith("/api/")||l.startsWith(`${location.origin}/api/`))&&s.then(d,()=>{}),s}}
1
+ const c="x-domma-cms-version";export function noticeFor(t,n){const e=typeof n=="string"?n.trim():"";return e?t.baseline?e===t.baseline||e===t.dismissed?{baseline:t.baseline,show:null}:{baseline:t.baseline,show:e}:{baseline:e,show:null}:{baseline:t.baseline,show:null}}const i={baseline:null,dismissed:null,showing:null};let a=!1,o=null;function d(t){if(!o){o=document.createElement("div"),o.className="dm-update-notice",o.setAttribute("role","status");const n=document.createElement("span");n.className="dm-update-notice__text";const e=document.createElement("button");e.type="button",e.className="btn btn-sm btn-primary",e.textContent="Reload",e.addEventListener("click",()=>location.reload());const s=document.createElement("button");s.type="button",s.className="btn btn-sm btn-ghost",s.textContent="Later",s.addEventListener("click",()=>{i.dismissed=i.showing,i.showing=null,o.hidden=!0}),o.append(n,e,s),document.body.appendChild(o)}o.querySelector(".dm-update-notice__text").textContent=`Domma CMS has been updated to ${t}. This tab is still running ${i.baseline} - save what you are working on, then reload so new settings are saved properly.`,o.hidden=!1}let l=null;export function renderCmsVersion(){const t=document.getElementById("topbar-cms-version");!t||!l||(t.textContent=l,t.parentElement.hidden=!1,t.hidden=!1)}function u(t){try{const n=t.headers.get(c);n&&n.trim()&&(l=n.trim(),renderCmsVersion());const e=noticeFor(i,n);i.baseline=e.baseline,e.show&&e.show!==i.showing&&(i.showing=e.show,d(e.show))}catch{}}export function installUpdateNotice(){if(a||typeof window>"u"||typeof window.fetch!="function")return;a=!0;const t=window.fetch;window.fetch=function(n,e){const s=t.call(this,n,e),r=typeof n=="string"?n:n&&n.url||"";return(r.startsWith("/api/")||r.startsWith(`${location.origin}/api/`))&&s.then(u,()=>{}),s}}