domma-cms 1.8.1 → 1.8.3

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,23 @@
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";$(()=>{K(document),tt(),mt(),ot(),it(),et(),(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(N[t])return E.toast(`${N[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={},N={};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 P=null,A=!1;document.addEventListener("dm:sidebar-rebuild",()=>{if(P){A=!0;return}P=(async()=>{do{A=!1;try{await j(await f())}catch{}}while(A)})().finally(()=>{P=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/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/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:"blockEditor",title:"New Block - Domma CMS"},{path:"/blocks/edit/:name",view:"blockEditor",title:"Edit Block - Domma CMS"},{path:"/components",view:"components",title:"Components - Domma CMS"},{path:"/components/new",view:"componentEditor",title:"New Component - Domma CMS"},{path:"/components/edit/:name",view:"componentEditor",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"},blockEditor:{displayName:"Blocks",section:"Edit",icon:"box"},componentEditor:{displayName:"Components",section:"Edit",icon:"component"},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&&(N[`/${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(`
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(N[t])return E.toast(`${N[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={},N={};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 P=null,A=!1;document.addEventListener("dm:sidebar-rebuild",()=>{if(P){A=!0;return}P=(async()=>{do{A=!1;try{await j(await f())}catch{}}while(A)})().finally(()=>{P=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/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/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:"blockEditor",title:"New Block - Domma CMS"},{path:"/blocks/edit/:name",view:"blockEditor",title:"Edit Block - Domma CMS"},{path:"/components",view:"components",title:"Components - Domma CMS"},{path:"/components/new",view:"componentEditor",title:"New Component - Domma CMS"},{path:"/components/edit/:name",view:"componentEditor",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"},blockEditor:{displayName:"Blocks",section:"Edit",icon:"box"},componentEditor:{displayName:"Components",section:"Edit",icon:"component"},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&&(N[`/${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
2
  ${o?`<img id="topbar-avatar" class="topbar-avatar" src="${d(o)}" alt="">`:""}
3
3
  <span id="topbar-user-name" class="topbar-user-name">${d(t.name)}</span>
4
4
  <span class="topbar-role-badge topbar-role-badge--${d(t.role)}">${e}</span>
5
- `),$("#topbar-actions").html(`
5
+ `),$("#topbar-actions").get(0).innerHTML=`
6
6
  <a href="#/system/notifications" id="topbar-bell" class="topbar-action-link" data-tooltip="Notifications" data-tooltip-placement="bottom" hidden>
7
7
  <span data-icon="bell"></span>
8
- <span>Notifications</span>
8
+ <span class="topbar-action-label">Notifications</span>
9
9
  <span id="topbar-bell-badge" class="topbar-bell-badge" hidden></span>
10
10
  </a>
11
11
  <a href="#/my-profile" class="topbar-action-link" data-tooltip="My Profile" data-tooltip-placement="bottom">
12
12
  <span data-icon="user"></span>
13
- <span>My Profile</span>
13
+ <span class="topbar-action-label">My Profile</span>
14
14
  </a>
15
15
  <a href="#/settings" id="topbar-settings" class="topbar-action-link" data-tooltip="Settings" data-tooltip-placement="bottom" hidden>
16
16
  <span data-icon="settings"></span>
17
- <span>Settings</span>
17
+ <span class="topbar-action-label">Settings</span>
18
18
  </a>
19
19
  <a href="#" id="topbar-logout-btn" class="topbar-action-link topbar-signout" data-tooltip="Sign out" data-tooltip-placement="bottom">
20
20
  <span data-icon="log-out"></span>
21
- <span>Sign out</span>
21
+ <span class="topbar-action-label">Sign out</span>
22
22
  </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}})})()});
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}})})()});
@@ -0,0 +1 @@
1
+ export const PHONE_QUERY="(max-width: 768px)",OPEN_CLASS="dm-sidebar-open";export function drawerNext(t,n){return n==="toggle"?!t:!1}export const OVER_DRAWER='.dm-slideover, domma-modal, dialog[open], [aria-modal="true"], .dm-admin-sidebar-flyout, .dm-help-pop';export function escapeCloses({open:t,handled:n,layerAbove:a}){return t&&!n&&!a}let m=!1;export function installSidebarDrawer(){if(m)return;const t=document.getElementById("topbar-sidebar-toggle"),n=document.getElementById("admin-sidebar");if(!t||!n)return;m=!0;const a=typeof matchMedia=="function"?matchMedia(PHONE_QUERY):null,i=()=>document.body.classList.contains(OPEN_CLASS),c=document.querySelector(".dashboard-main"),f=()=>[...document.querySelectorAll(OVER_DRAWER)].some(e=>!n.contains(e)&&e.getClientRects().length>0&&getComputedStyle(e).visibility!=="hidden"),p=(e,{focus:s=!1}={})=>{document.body.classList.toggle(OPEN_CLASS,e),t.setAttribute("aria-expanded",String(e));const o=e?"Close menu":"Open menu";t.setAttribute("aria-label",o),c&&(c.inert=e),!e&&n.contains(document.activeElement)&&t.focus({preventScroll:!0}),e&&s&&requestAnimationFrame(()=>{[...n.querySelectorAll("a[href], summary, button")].find(u=>u.getClientRects().length&&getComputedStyle(u).visibility==="visible")?.focus({preventScroll:!0})})},r=(e,s)=>{const o=i(),d=drawerNext(o,e);return d!==o&&p(d,s),o};t.addEventListener("click",()=>r("toggle",{focus:!0})),document.querySelector(".admin-sidebar-backdrop")?.addEventListener("click",()=>r("backdrop")),window.addEventListener("hashchange",()=>r("navigate"));let l=!1;window.addEventListener("keydown",e=>{e.key==="Escape"&&(l=i()&&f())},!0),document.addEventListener("keydown",e=>{e.key==="Escape"&&escapeCloses({open:i(),handled:e.defaultPrevented,layerAbove:l})&&(r("escape"),t.focus({preventScroll:!0}))}),a?.addEventListener?.("change",e=>{e.matches||r("desktop")});try{I.scan(t)}catch{}}
@@ -1 +1 @@
1
- export const MIN_WIDTH=180,MAX_WIDTH=480,COLLAPSED_WIDTH=56,COLLAPSE_SNAP=120,STEP=16,BIG_STEP=64,WIDTH_KEY="sidebar.width",COLLAPSED_KEY="sidebar.collapsed";export function clampWidth(e){return Math.max(180,Math.min(480,Math.round(e)))}export function parseWidth(e){const r=Number.parseInt(e,10);return Number.isFinite(r)&&r>=180&&r<=480?r:null}export function dragOutcome(e){return e<120?{collapsed:!0,width:null}:{collapsed:!1,width:clampWidth(e)}}export function keyOutcome({key:e,shiftKey:r=!1},{width:t,collapsed:i}){const n=r?64:16;switch(e){case"ArrowLeft":return i?{collapsed:!0,width:null}:t<=180?{collapsed:!0,width:null}:{collapsed:!1,width:clampWidth(t-n)};case"ArrowRight":return i?{collapsed:!1,width:null}:{collapsed:!1,width:clampWidth(t+n)};case"Home":return{collapsed:!1,width:180};case"End":return{collapsed:!1,width:480};case"Enter":case" ":return{collapsed:!i,width:null};default:return null}}export function collapseButtonMarkup(){return'<button type="button" class="btn btn-sm btn-ghost dm-admin-sidebar-collapse" aria-expanded="true" aria-label="Collapse sidebar" title="Collapse sidebar"><span data-icon="chevrons-left" data-icon-size="16"></span></button>'}function c(e){return e.classList.contains("is-collapsed")}function N(){try{return parseWidth(S.get(WIDTH_KEY))}catch{return null}}function u(e,r){try{r==null?S.remove(e):S.set(e,r)}catch{}}function g(e,r){e.classList.toggle("is-collapsed",r);const t=e.querySelector(".dm-admin-sidebar-collapse");if(t){const i=r?"Expand sidebar":"Collapse sidebar";t.setAttribute("aria-expanded",String(!r)),t.setAttribute("aria-label",i),t.title=i}r?e.querySelector(".dm-admin-sidebar")?.scrollTo?.(0,0):o();for(const i of e.querySelectorAll("details > summary"))r?i.setAttribute("aria-expanded","false"):i.removeAttribute("aria-expanded");D(e)}function m(e){return!!e.querySelector(".dm-admin-sidebar.is-arranging")}function v(e){return c(e)?56:parseInt(e.style.width,10)||e.getBoundingClientRect().width}function D(e){const r=e.querySelector(".dm-admin-sidebar-handle");if(r)if(c(e))r.setAttribute("aria-valuenow",String(180)),r.setAttribute("aria-valuetext","Collapsed");else{const t=Math.round(v(e));if(!t)return;r.setAttribute("aria-valuenow",String(clampWidth(t))),r.setAttribute("aria-valuetext",`${t} pixels`)}}function f(e){D(e),e.__dmGutter?.()}function w(e,r){g(e,r),u(COLLAPSED_KEY,r?!0:null),f(e);const t=i=>{i.target!==e||i.propertyName!=="width"||(e.removeEventListener("transitionend",t),f(e))};e.addEventListener("transitionend",t)}function q(e,r){e.style.width=r+"px",u(WIDTH_KEY,r)}let a=null,p=null;function o({restoreFocus:e=!1}={}){if(!a)return;a.remove();const r=p?.querySelector(":scope > summary");r?.setAttribute("aria-expanded","false"),e&&r?.focus(),a=null,p=null}function P(e,r,{focus:t=!1}={}){const i=p===r;if(o(),i)return;const n=r.querySelector(":scope > summary"),d=r.querySelector(":scope > .sidebar-children");if(!n||!d)return;const x=e.querySelector(".dm-admin-sidebar");a=document.createElement("div"),a.className="dm-admin-sidebar-flyout";const l=document.createElement("nav");l.className=x?x.className:"dm-admin-sidebar",l.setAttribute("aria-label",n.querySelector(".sidebar-text")?.textContent.trim()||"Folder");const b=document.createElement("div");b.className="dm-admin-sidebar-flyout-title",b.textContent=l.getAttribute("aria-label"),l.appendChild(b);for(const s of d.children)l.appendChild(s.cloneNode(!0));for(const s of l.querySelectorAll(".sidebar-children"))s.style.maxHeight="";a.appendChild(l);for(const s of["data-menu-hover","data-menu-active"])e.hasAttribute(s)&&a.setAttribute(s,e.getAttribute(s));const A=e.style.getPropertyValue("--dm-menu-highlight");A&&a.style.setProperty("--dm-menu-highlight",A),document.body.appendChild(a);const y=e.getBoundingClientRect(),T=n.getBoundingClientRect(),I=window.innerHeight-8;a.style.maxHeight=`${I-8}px`;const{width:L,height:C}=a.getBoundingClientRect(),M=y.right+4+L<=window.innerWidth-8?y.right+4:y.left-4-L;a.style.left=`${Math.round(Math.max(8,M))}px`,a.style.top=`${Math.round(Math.max(8,Math.min(T.top,I-C)))}px`,p=r,n.setAttribute("aria-expanded","true"),t&&a.querySelector("a, summary")?.focus(),a.addEventListener("click",s=>{s.target.closest("a[href]")&&o()}),a.addEventListener("keydown",s=>{if(s.key==="Escape"){s.preventDefault(),o({restoreFocus:!0});return}if(s.key!=="Tab")return;const _=[...a.querySelectorAll("a[href], summary")].filter(h=>h.offsetParent);if(s.shiftKey&&document.activeElement===_[0])s.preventDefault(),o({restoreFocus:!0});else if(!s.shiftKey&&document.activeElement===_.at(-1)){s.preventDefault();const h=[...e.querySelectorAll('a[href], summary, button, [tabindex="0"]')].filter(H=>H.offsetParent),W=h[h.indexOf(n)+1];o(),(W||n).focus()}}),a.addEventListener("focusout",s=>{!a?.contains(s.relatedTarget)&&!n.contains(s.relatedTarget)&&s.relatedTarget&&o()})}function k(e){if(e.__dmSizeWired)return;e.__dmSizeWired=!0,e.addEventListener("click",t=>{if(!c(e))return;const i=t.target.closest("summary");!i||!e.contains(i)||(t.preventDefault(),P(e,i.parentElement,{focus:t.detail===0}))}),e.addEventListener("keydown",t=>{t.key==="Escape"&&a&&o({restoreFocus:!0})}),document.addEventListener("pointerdown",t=>{!a||a.contains(t.target)||p?.querySelector(":scope > summary")?.contains(t.target)||o()}),window.addEventListener("hashchange",()=>o()),window.addEventListener("resize",()=>o()),document.addEventListener("pointermove",t=>{const i=e.__dmDrag;if(!i||t.pointerId!==i.pointerId)return;if(t.pointerType==="mouse"&&t.buttons===0)return r(t);const n=t.clientX-i.x;if(!i.moved&&Math.abs(n)<3)return;i.moved=!0;const d=dragOutcome(i.width+n);d.collapsed!==c(e)&&g(e,d.collapsed),d.collapsed||(e.style.width=d.width+"px"),f(e)});const r=t=>{const i=e.__dmDrag;!i||t.pointerId!==i.pointerId||(e.__dmDrag=null,e.classList.remove("is-resizing"),document.body.classList.remove("dm-sidebar-resizing"),i.moved&&(c(e)?(e.style.width=i.inline,u(COLLAPSED_KEY,!0)):(u(COLLAPSED_KEY,null),u(WIDTH_KEY,parseInt(e.style.width,10))),f(e)))};document.addEventListener("pointerup",r),document.addEventListener("pointercancel",r)}export function wireSidebarSize(e){k(e),o();const r=N();r&&(e.style.width=r+"px");const t=document.createElement("div");t.className="dm-admin-sidebar-handle",t.tabIndex=0,t.setAttribute("role","separator"),t.setAttribute("aria-orientation","vertical"),t.setAttribute("aria-label","Resize sidebar"),e.id&&t.setAttribute("aria-controls",e.id),t.setAttribute("aria-valuemin",String(180)),t.setAttribute("aria-valuemax",String(480)),t.title="Drag to resize - double-click to reset",e.appendChild(t);let i=!1;try{i=S.get(COLLAPSED_KEY)===!0}catch{}g(e,i),e.querySelector(".dm-admin-sidebar-collapse")?.addEventListener("click",()=>w(e,!c(e))),t.addEventListener("pointerdown",n=>{if(!(n.button!==0||m(e))){e.__dmDrag={pointerId:n.pointerId,x:n.clientX,width:v(e),inline:e.style.width,moved:!1};try{t.setPointerCapture(n.pointerId)}catch{}e.classList.add("is-resizing"),document.body.classList.add("dm-sidebar-resizing"),n.preventDefault()}}),t.addEventListener("dblclick",()=>{m(e)||(e.style.width="",u(WIDTH_KEY,null),w(e,!1))}),t.addEventListener("keydown",n=>{if(m(e))return;const d=keyOutcome(n,{width:v(e),collapsed:c(e)});d&&(n.preventDefault(),d.collapsed!==c(e)&&w(e,d.collapsed),d.width!=null&&q(e,d.width),f(e))}),f(e)}
1
+ import{PHONE_QUERY as D}from"./sidebar-drawer.js";export const MIN_WIDTH=180,MAX_WIDTH=480,COLLAPSED_WIDTH=56,COLLAPSE_SNAP=120,STEP=16,BIG_STEP=64,WIDTH_KEY="sidebar.width",COLLAPSED_KEY="sidebar.collapsed";export function railShown(e,r){return e===!0&&!r}function I(){return typeof matchMedia=="function"&&matchMedia(D).matches}function M(){try{return S.get(COLLAPSED_KEY)===!0}catch{return!1}}export function clampWidth(e){return Math.max(MIN_WIDTH,Math.min(MAX_WIDTH,Math.round(e)))}export function parseWidth(e){const r=Number.parseInt(e,10);return Number.isFinite(r)&&r>=MIN_WIDTH&&r<=MAX_WIDTH?r:null}export function dragOutcome(e){return e<COLLAPSE_SNAP?{collapsed:!0,width:null}:{collapsed:!1,width:clampWidth(e)}}export function keyOutcome({key:e,shiftKey:r=!1},{width:t,collapsed:i}){const s=r?BIG_STEP:STEP;switch(e){case"ArrowLeft":return i?{collapsed:!0,width:null}:t<=MIN_WIDTH?{collapsed:!0,width:null}:{collapsed:!1,width:clampWidth(t-s)};case"ArrowRight":return i?{collapsed:!1,width:null}:{collapsed:!1,width:clampWidth(t+s)};case"Home":return{collapsed:!1,width:MIN_WIDTH};case"End":return{collapsed:!1,width:MAX_WIDTH};case"Enter":case" ":return{collapsed:!i,width:null};default:return null}}export function collapseButtonMarkup(){return'<button type="button" class="btn btn-sm btn-ghost dm-admin-sidebar-collapse" aria-expanded="true" aria-label="Collapse sidebar" title="Collapse sidebar"><span data-icon="chevrons-left" data-icon-size="16"></span></button>'}function o(e){return e.classList.contains("is-collapsed")}function z(){try{return parseWidth(S.get(WIDTH_KEY))}catch{return null}}function f(e,r){try{r==null?S.remove(e):S.set(e,r)}catch{}}function y(e,r){e.classList.toggle("is-collapsed",r);const t=e.querySelector(".dm-admin-sidebar-collapse");if(t){const i=r?"Expand sidebar":"Collapse sidebar";t.setAttribute("aria-expanded",String(!r)),t.setAttribute("aria-label",i),t.title=i}r?e.querySelector(".dm-admin-sidebar")?.scrollTo?.(0,0):d();for(const i of e.querySelectorAll("details > summary"))r?i.setAttribute("aria-expanded","false"):i.removeAttribute("aria-expanded");q(e)}function g(e){return!!e.querySelector(".dm-admin-sidebar.is-arranging")}function v(e){return o(e)?COLLAPSED_WIDTH:parseInt(e.style.width,10)||e.getBoundingClientRect().width}function q(e){const r=e.querySelector(".dm-admin-sidebar-handle");if(r)if(o(e))r.setAttribute("aria-valuenow",String(MIN_WIDTH)),r.setAttribute("aria-valuetext","Collapsed");else{const t=Math.round(v(e));if(!t)return;r.setAttribute("aria-valuenow",String(clampWidth(t))),r.setAttribute("aria-valuetext",`${t} pixels`)}}function u(e){q(e),e.__dmGutter?.()}function x(e,r){y(e,r),f(COLLAPSED_KEY,r?!0:null),u(e);const t=i=>{i.target!==e||i.propertyName!=="width"||(e.removeEventListener("transitionend",t),u(e))};e.addEventListener("transitionend",t)}function H(e,r){e.style.width=r+"px",f(WIDTH_KEY,r)}let n=null,p=null;function d({restoreFocus:e=!1}={}){if(!n)return;n.remove();const r=p?.querySelector(":scope > summary");r?.setAttribute("aria-expanded","false"),e&&r?.focus(),n=null,p=null}function F(e,r,{focus:t=!1}={}){const i=p===r;if(d(),i)return;const s=r.querySelector(":scope > summary"),c=r.querySelector(":scope > .sidebar-children");if(!s||!c)return;const w=e.querySelector(".dm-admin-sidebar");n=document.createElement("div"),n.className="dm-admin-sidebar-flyout";const l=document.createElement("nav");l.className=w?w.className:"dm-admin-sidebar",l.setAttribute("aria-label",s.querySelector(".sidebar-text")?.textContent.trim()||"Folder");const b=document.createElement("div");b.className="dm-admin-sidebar-flyout-title",b.textContent=l.getAttribute("aria-label"),l.appendChild(b);for(const a of c.children)l.appendChild(a.cloneNode(!0));for(const a of l.querySelectorAll(".sidebar-children"))a.style.maxHeight="";n.appendChild(l);for(const a of["data-menu-hover","data-menu-active"])e.hasAttribute(a)&&n.setAttribute(a,e.getAttribute(a));const A=e.style.getPropertyValue("--dm-menu-highlight");A&&n.style.setProperty("--dm-menu-highlight",A),document.body.appendChild(n);const m=e.getBoundingClientRect(),P=s.getBoundingClientRect(),L=window.innerHeight-8;n.style.maxHeight=`${L-8}px`;const{width:C,height:k}=n.getBoundingClientRect(),N=m.right+4+C<=window.innerWidth-8?m.right+4:m.left-4-C;n.style.left=`${Math.round(Math.max(8,N))}px`,n.style.top=`${Math.round(Math.max(8,Math.min(P.top,L-k)))}px`,p=r,s.setAttribute("aria-expanded","true"),t&&n.querySelector("a, summary")?.focus(),n.addEventListener("click",a=>{a.target.closest("a[href]")&&d()}),n.addEventListener("keydown",a=>{if(a.key==="Escape"){a.preventDefault(),d({restoreFocus:!0});return}if(a.key!=="Tab")return;const _=[...n.querySelectorAll("a[href], summary")].filter(h=>h.offsetParent);if(a.shiftKey&&document.activeElement===_[0])a.preventDefault(),d({restoreFocus:!0});else if(!a.shiftKey&&document.activeElement===_.at(-1)){a.preventDefault();const h=[...e.querySelectorAll('a[href], summary, button, [tabindex="0"]')].filter(W=>W.offsetParent),T=h[h.indexOf(s)+1];d(),(T||s).focus()}}),n.addEventListener("focusout",a=>{!n?.contains(a.relatedTarget)&&!s.contains(a.relatedTarget)&&a.relatedTarget&&d()})}function O(e){if(e.__dmSizeWired)return;e.__dmSizeWired=!0,e.addEventListener("click",t=>{if(!o(e))return;const i=t.target.closest("summary");!i||!e.contains(i)||(t.preventDefault(),F(e,i.parentElement,{focus:t.detail===0}))}),e.addEventListener("keydown",t=>{t.key==="Escape"&&n&&d({restoreFocus:!0})}),document.addEventListener("pointerdown",t=>{!n||n.contains(t.target)||p?.querySelector(":scope > summary")?.contains(t.target)||d()}),window.addEventListener("hashchange",()=>d()),window.addEventListener("resize",()=>d()),document.addEventListener("pointermove",t=>{const i=e.__dmDrag;if(!i||t.pointerId!==i.pointerId)return;if(t.pointerType==="mouse"&&t.buttons===0)return r(t);const s=t.clientX-i.x;if(!i.moved&&Math.abs(s)<3)return;i.moved=!0;const c=dragOutcome(i.width+s);c.collapsed!==o(e)&&y(e,c.collapsed),c.collapsed||(e.style.width=c.width+"px"),u(e)});const r=t=>{const i=e.__dmDrag;!i||t.pointerId!==i.pointerId||(e.__dmDrag=null,e.classList.remove("is-resizing"),document.body.classList.remove("dm-sidebar-resizing"),i.moved&&(o(e)?(e.style.width=i.inline,f(COLLAPSED_KEY,!0)):(f(COLLAPSED_KEY,null),f(WIDTH_KEY,parseInt(e.style.width,10))),u(e)))};document.addEventListener("pointerup",r),document.addEventListener("pointercancel",r),typeof matchMedia=="function"&&matchMedia(D).addEventListener?.("change",t=>{const i=railShown(M(),t.matches);i!==o(e)&&y(e,i),u(e)})}export function wireSidebarSize(e){O(e),d();const r=z();r&&(e.style.width=r+"px");const t=document.createElement("div");t.className="dm-admin-sidebar-handle",t.tabIndex=0,t.setAttribute("role","separator"),t.setAttribute("aria-orientation","vertical"),t.setAttribute("aria-label","Resize sidebar"),e.id&&t.setAttribute("aria-controls",e.id),t.setAttribute("aria-valuemin",String(MIN_WIDTH)),t.setAttribute("aria-valuemax",String(MAX_WIDTH)),t.title="Drag to resize - double-click to reset",e.appendChild(t),y(e,railShown(M(),I())),e.querySelector(".dm-admin-sidebar-collapse")?.addEventListener("click",()=>{I()||x(e,!o(e))}),t.addEventListener("pointerdown",i=>{if(!(i.button!==0||g(e))){e.__dmDrag={pointerId:i.pointerId,x:i.clientX,width:v(e),inline:e.style.width,moved:!1};try{t.setPointerCapture(i.pointerId)}catch{}e.classList.add("is-resizing"),document.body.classList.add("dm-sidebar-resizing"),i.preventDefault()}}),t.addEventListener("dblclick",()=>{g(e)||(e.style.width="",f(WIDTH_KEY,null),x(e,!1))}),t.addEventListener("keydown",i=>{if(g(e))return;const s=keyOutcome(i,{width:v(e),collapsed:o(e)});s&&(i.preventDefault(),s.collapsed!==o(e)&&x(e,s.collapsed),s.width!=null&&H(e,s.width),u(e))}),u(e)}
@@ -1 +1 @@
1
- export const KIND_LABEL={page:"Page",post:"Post",media:"Media",menu:"Menu",category:"Category"},KIND_PLURAL={page:"Pages",post:"Posts",media:"Media",menu:"Menus",category:"Categories"},KIND_ICON={page:"file-text",post:"edit-3",media:"image",menu:"menu",category:"tag"},ACTION={create:{text:"New",tone:"ok"},rename:{text:"New, renamed",tone:"warn"},update:{text:"Update",tone:"info"},keep:{text:"Left as is",tone:"muted"},skip:{text:"Skipped",tone:"muted"}},RESULT={created:{text:"Made",tone:"ok"},updated:{text:"Updated",tone:"info"},kept:{text:"Left as is",tone:"muted"},skipped:{text:"Skipped",tone:"muted"},failed:{text:"Failed",tone:"bad"}},PLAN_FILTERS=[{id:"all",label:"All"},{id:"new",label:"New"},{id:"update",label:"Updates"},{id:"renamed",label:"Renamed"},{id:"keep",label:"Left as is"},{id:"skip",label:"Skipped"},{id:"rebuild",label:"Needs rebuilding"}],REPORT_FILTERS=[{id:"all",label:"All"},{id:"created",label:"Made"},{id:"updated",label:"Updated"},{id:"kept",label:"Left as is"},{id:"skipped",label:"Skipped"},{id:"failed",label:"Failed"},{id:"rebuild",label:"Needs rebuilding"}];const d=e=>!!(e.builder||e.shortcodes?.length);export function planMatches(e,t){switch(t){case"new":return e.action==="create"||e.action==="rename";case"update":return e.action==="update";case"renamed":return e.action==="rename"||!!e.replaces;case"keep":return e.action==="keep";case"skip":return e.action==="skip";case"rebuild":return d(e);default:return!0}}export function reportMatches(e,t){return t==="rebuild"?d(e):t==="all"||!t||e.result===t}export function counts(e,t,i,o=""){const n=e.filter(s=>!o||s.kind===o);return Object.fromEntries(t.map(s=>[s.id,n.filter(a=>i(a,s.id)).length]))}export function kindTabs(e){const t=["page","post","media","menu","category"],i={};for(const o of e)i[o.kind]=(i[o.kind]||0)+1;return[{id:"",label:"Everything",count:e.length},...t.filter(o=>i[o]).map(o=>({id:o,label:KIND_PLURAL[o],count:i[o]}))]}export function planRow(e){const t=ACTION[e.action]||ACTION.skip,i=e.target?e.kind==="menu"?`Menu "${e.target}"`:e.target:"",o=[KIND_LABEL[e.kind]||e.kind];return e.status&&(e.kind==="page"||e.kind==="post")&&o.push(e.status),e.comments&&o.push(`${e.comments} comment${e.comments===1?"":"s"}`),e.count&&o.push(`${e.count} item${e.count===1?"":"s"}`),{key:e.key,kind:e.kind,icon:KIND_ICON[e.kind]||"file",title:e.title||"(untitled)",pill:e.replaces?"Replaces a page":t.text,pillClass:`is-${e.replaces?"warn":t.tone}`,where:i,meta:o.join(" \xB7 "),reason:e.reason||"",rebuild:[e.builder?`Built with ${e.builder}`:"",...(e.shortcodes||[]).map(n=>`[${n}]`)].filter(Boolean).join(" "),chosen:!!e.choice}}export function reportRow(e){const t=RESULT[e.result]||RESULT.skipped;return{key:e.key,kind:e.kind,icon:KIND_ICON[e.kind]||"file",title:e.title||"(untitled)",pill:t.text,pillClass:`is-${t.tone}`,where:e.target||"",meta:[KIND_LABEL[e.kind]||e.kind,e.format==="html"?"kept as HTML":""].filter(Boolean).join(" \xB7 "),reason:[e.reason,...e.notes||[]].filter(Boolean).join(" "),rebuild:[e.builder?`Built with ${e.builder}`:"",...(e.shortcodes||[]).map(i=>`[${i}]`)].filter(Boolean).join(" ")}}export function choiceItems(e,t){const i=[];return t&&i.push({id:"reset",label:"Undo my choice",icon:"rotate-ccw"}),t!=="skip"&&e.action!=="skip"&&e.action!=="keep"&&i.push({id:"skip",label:"Skip this",icon:"x-circle"}),t!=="overwrite"&&e.action==="keep"&&i.push({id:"overwrite",label:"Overwrite my changes here",icon:"refresh-cw"}),t!=="overwrite"&&e.action==="rename"&&(e.kind==="page"||e.kind==="post")&&e.wanted&&e.kind==="page"&&i.push({id:"overwrite",label:`Replace the page at ${e.wanted}`,icon:"refresh-cw"}),t!=="import"&&e.action==="skip"&&/Deleted (on this site|from the Blog)/.test(e.reason||"")&&i.push({id:"import",label:"Import again",icon:"download"}),i}export function applyChoice(e,t,i){const o={...e||{}};return!i||i==="reset"?delete o[t]:o[t]=i,o}export function defaultOptions(e=!1){return{posts:e?"blog":"pages",media:"download",comments:!0,menus:!0,redirects:!0,drafts:!0,choices:{}}}export function cleanOptions(e={},t=!1){const i=defaultOptions(t),o=(n,s,a)=>s.includes(n)?n:a;return{posts:o(e.posts,t?["blog","pages","skip"]:["pages","skip"],i.posts),media:o(e.media,["download","zip","skip"],i.media),comments:e.comments!==!1,menus:e.menus!==!1,redirects:e.redirects!==!1,drafts:e.drafts!==!1,choices:Object.fromEntries(Object.entries(e.choices||{}).filter(([n,s])=>typeof n=="string"&&["skip","overwrite","import"].includes(s)))}}export function optionsSnapshot(e){const t=cleanOptions(e,!0),i=Object.keys(t.choices).sort().map(o=>`${o}=${t.choices[o]}`).join(",");return[t.posts,t.media,t.comments,t.menus,t.redirects,t.drafts,i].join("|")}export const isDirty=(e,t)=>optionsSnapshot(e)!==optionsSnapshot(defaultOptions(t)),draftKey=e=>e?`wordpress-import.draft.${e}`:"";export function liveDrafts(e,t,i){if(!e||typeof e!="object"||!e.items||typeof e.items!="object")return{items:{},pruned:!1};if(e.owner&&i&&e.owner!==i)return{items:{},pruned:!1};const o={};let n=!1;for(const[s,a]of Object.entries(e.items))t.includes(s)&&a?.options&&a.was===s?o[s]=a:n=!0;return{items:o,pruned:n}}export function withDraft(e,t,i,o){const n={...e&&e.owner===t&&e.items||{}};return o?n[i]=o:delete n[i],{owner:t,items:n}}export function draftQuestion({when:e="",file:t=""}={}){return{title:"Choices you left last time",text:`You changed the import options${t?` for ${t}`:""}${e?` (${e})`:""} and left before running it. Throw away those choices and start from the defaults?`,confirmText:"Throw away",cancelText:"Keep them"}}export function progressText(e){if(!e)return"";const t=e.total?` \xB7 ${e.done} of ${e.total}`:"";return`${e.phase||"Working"}${t}${e.current?` \xB7 ${String(e.current).slice(0,80)}`:""}`}export const progressPercent=e=>e?.total?Math.min(100,Math.round(e.done/e.total*100)):0;export function planTiles(e){const t=e?.summary?.counts||{},i=o=>t[o]?t[o].total-t[o].skip:0;return[{id:"page",label:"Pages",value:i("page"),of:t.page?.total||0},{id:"post",label:"Posts",value:i("post"),of:t.post?.total||0},{id:"media",label:"Media",value:i("media"),of:t.media?.total||0},{id:"menu",label:"Menus",value:i("menu"),of:t.menu?.total||0},{id:"comments",label:"Comments",value:e?.summary?.comments||0,of:0},{id:"redirects",label:"Redirects",value:e?.summary?.redirects||0,of:0}].map(o=>({...o,sub:o.of&&o.of!==o.value?`of ${o.of}`:""}))}export function historyRow(e,t=i=>i){const i=e.summary||{},o=Object.values(i.kinds||{}).reduce((a,l)=>a+(l.created||0),0),n=Object.values(i.kinds||{}).reduce((a,l)=>a+(l.updated||0),0),s=[];return o&&s.push(`${o} made`),n&&s.push(`${n} updated`),i.redirects?.created&&s.push(`${i.redirects.created} redirect${i.redirects.created===1?"":"s"}`),i.rebuild&&s.push(`${i.rebuild} to rebuild`),i.failed&&s.push(`${i.failed} failed`),e.status==="failed"&&s.splice(0,s.length,"Stopped before the end - run it again to finish"),{id:e.id,title:e.siteTitle||e.source||"WordPress site",meta:[t(e.at),e.by,e.file].filter(Boolean).join(" \xB7 "),summary:s.join(", ")||"Nothing changed",pill:e.status==="failed"?"Stopped":e.status==="partial"?"Some failed":"Done",pillClass:e.status==="failed"||e.status==="partial"?"is-bad":"is-ok"}}export function stagedRow(e,t=i=>i){const i=e.counts||{},o=[i.page&&`${i.page} pages`,i.post&&`${i.post} posts`,i.attachment&&`${i.attachment} media`].filter(Boolean);return{id:e.id,title:e.siteTitle||e.fileName||"WordPress export",meta:[e.fileName,t(e.at),o.join(", ")].filter(Boolean).join(" \xB7 "),pill:e.uploads?"Uploads zip added":"Waiting",pillClass:e.uploads?"is-ok":"is-muted"}}
1
+ export const KIND_LABEL={page:"Page",post:"Post",product:"Product",media:"Media",menu:"Menu",category:"Category"},KIND_PLURAL={page:"Pages",post:"Posts",product:"Products",media:"Media",menu:"Menus",category:"Categories"},KIND_ICON={page:"file-text",post:"edit-3",product:"shopping-bag",media:"image",menu:"menu",category:"tag"},PRODUCT_TYPE_LABEL={simple:"Simple",variable:"With options",grouped:"Grouped",external:"External"},ACTION={create:{text:"New",tone:"ok"},rename:{text:"New, renamed",tone:"warn"},update:{text:"Update",tone:"info"},keep:{text:"Left as is",tone:"muted"},skip:{text:"Skipped",tone:"muted"}},RESULT={created:{text:"Made",tone:"ok"},updated:{text:"Updated",tone:"info"},kept:{text:"Left as is",tone:"muted"},skipped:{text:"Skipped",tone:"muted"},failed:{text:"Failed",tone:"bad"}},PLAN_FILTERS=[{id:"all",label:"All"},{id:"new",label:"New"},{id:"update",label:"Updates"},{id:"renamed",label:"Renamed"},{id:"keep",label:"Left as is"},{id:"skip",label:"Skipped"},{id:"rebuild",label:"Needs rebuilding"}],REPORT_FILTERS=[{id:"all",label:"All"},{id:"created",label:"Made"},{id:"updated",label:"Updated"},{id:"kept",label:"Left as is"},{id:"skipped",label:"Skipped"},{id:"failed",label:"Failed"},{id:"rebuild",label:"Needs rebuilding"}];const p=e=>!!(e.builder||e.needs||e.shortcodes?.length),c=e=>[e.builder?`Built with ${e.builder}`:"",e.needs||"",...(e.shortcodes||[]).map(t=>`[${t}]`)].filter(Boolean).join(" ");export function planMatches(e,t){switch(t){case"new":return e.action==="create"||e.action==="rename";case"update":return e.action==="update";case"renamed":return e.action==="rename"||!!e.replaces;case"keep":return e.action==="keep";case"skip":return e.action==="skip";case"rebuild":return p(e);default:return!0}}export function reportMatches(e,t){return t==="rebuild"?p(e):t==="all"||!t||e.result===t}export function counts(e,t,o,i=""){const a=e.filter(s=>!i||s.kind===i);return Object.fromEntries(t.map(s=>[s.id,a.filter(n=>o(n,s.id)).length]))}export function kindTabs(e){const t=["page","post","product","media","menu","category"],o={};for(const i of e)o[i.kind]=(o[i.kind]||0)+1;return[{id:"",label:"Everything",count:e.length},...t.filter(i=>o[i]).map(i=>({id:i,label:KIND_PLURAL[i],count:o[i]}))]}export function planRow(e){const t=ACTION[e.action]||ACTION.skip,o=e.target?e.kind==="menu"?`Menu "${e.target}"`:e.target:"",i=[KIND_LABEL[e.kind]||e.kind];return e.status&&(e.kind==="page"||e.kind==="post")&&i.push(e.status),e.kind==="product"&&(e.productType&&i.push(PRODUCT_TYPE_LABEL[e.productType]||e.productType),e.variants&&i.push(`${e.variants} option${e.variants===1?"":"s"}`),e.action!=="skip"&&e.status&&i.push(e.status==="active"?"on sale":"draft")),e.comments&&i.push(`${e.comments} comment${e.comments===1?"":"s"}`),e.count&&i.push(`${e.count} item${e.count===1?"":"s"}`),{key:e.key,kind:e.kind,icon:KIND_ICON[e.kind]||"file",title:e.title||"(untitled)",pill:e.replaces?"Replaces a page":t.text,pillClass:`is-${e.replaces?"warn":t.tone}`,where:o,meta:i.join(" \xB7 "),reason:e.reason||"",rebuild:c(e),chosen:!!e.choice}}export function reportRow(e){const t=RESULT[e.result]||RESULT.skipped;return{key:e.key,kind:e.kind,icon:KIND_ICON[e.kind]||"file",title:e.title||"(untitled)",pill:t.text,pillClass:`is-${t.tone}`,where:e.target||"",meta:[KIND_LABEL[e.kind]||e.kind,e.format==="html"?"kept as HTML":""].filter(Boolean).join(" \xB7 "),reason:[e.reason,...e.notes||[]].filter(Boolean).join(" "),rebuild:c(e)}}export function choiceItems(e,t){const o=[];return t&&o.push({id:"reset",label:"Undo my choice",icon:"rotate-ccw"}),t!=="skip"&&e.action!=="skip"&&e.action!=="keep"&&o.push({id:"skip",label:"Skip this",icon:"x-circle"}),t!=="overwrite"&&e.action==="keep"&&o.push({id:"overwrite",label:"Overwrite my changes here",icon:"refresh-cw"}),t!=="overwrite"&&e.action==="rename"&&(e.kind==="page"||e.kind==="post")&&e.wanted&&e.kind==="page"&&o.push({id:"overwrite",label:`Replace the page at ${e.wanted}`,icon:"refresh-cw"}),t!=="import"&&e.action==="skip"&&/Deleted (on this site|from the Blog|from the Shop)/.test(e.reason||"")&&o.push({id:"import",label:"Import again",icon:"download"}),o}export function applyChoice(e,t,o){const i={...e||{}};return!o||o==="reset"?delete i[t]:i[t]=o,i}export function defaultOptions(e=!1){return{posts:e?"blog":"pages",media:"download",comments:!0,menus:!0,redirects:!0,drafts:!0,products:!0,choices:{}}}export function cleanOptions(e={},t=!1){const o=defaultOptions(t),i=(a,s,n)=>s.includes(a)?a:n;return{posts:i(e.posts,t?["blog","pages","skip"]:["pages","skip"],o.posts),media:i(e.media,["download","zip","skip"],o.media),comments:e.comments!==!1,menus:e.menus!==!1,redirects:e.redirects!==!1,drafts:e.drafts!==!1,products:e.products!==!1,choices:Object.fromEntries(Object.entries(e.choices||{}).filter(([a,s])=>typeof a=="string"&&["skip","overwrite","import"].includes(s)))}}export function optionsSnapshot(e){const t=cleanOptions(e,!0),o=Object.keys(t.choices).sort().map(i=>`${i}=${t.choices[i]}`).join(",");return[t.posts,t.media,t.comments,t.menus,t.redirects,t.drafts,t.products,o].join("|")}export const isDirty=(e,t)=>optionsSnapshot(e)!==optionsSnapshot(defaultOptions(t)),draftKey=e=>e?`wordpress-import.draft.${e}`:"";export function liveDrafts(e,t,o){if(!e||typeof e!="object"||!e.items||typeof e.items!="object")return{items:{},pruned:!1};if(e.owner&&o&&e.owner!==o)return{items:{},pruned:!1};const i={};let a=!1;for(const[s,n]of Object.entries(e.items))t.includes(s)&&n?.options&&n.was===s?i[s]=n:a=!0;return{items:i,pruned:a}}export function withDraft(e,t,o,i){const a={...e&&e.owner===t&&e.items||{}};return i?a[o]=i:delete a[o],{owner:t,items:a}}export function draftQuestion({when:e="",file:t=""}={}){return{title:"Choices you left last time",text:`You changed the import options${t?` for ${t}`:""}${e?` (${e})`:""} and left before running it. Throw away those choices and start from the defaults?`,confirmText:"Throw away",cancelText:"Keep them"}}export function progressText(e){if(!e)return"";const t=e.total?` \xB7 ${e.done} of ${e.total}`:"";return`${e.phase||"Working"}${t}${e.current?` \xB7 ${String(e.current).slice(0,80)}`:""}`}export const progressPercent=e=>e?.total?Math.min(100,Math.round(e.done/e.total*100)):0;export function planTiles(e){const t=e?.summary?.counts||{},o=i=>t[i]?t[i].total-t[i].skip:0;return[{id:"page",label:"Pages",value:o("page"),of:t.page?.total||0},{id:"post",label:"Posts",value:o("post"),of:t.post?.total||0},...t.product?[{id:"product",label:"Products",value:o("product"),of:t.product.total}]:[],{id:"media",label:"Media",value:o("media"),of:t.media?.total||0},{id:"menu",label:"Menus",value:o("menu"),of:t.menu?.total||0},{id:"comments",label:"Comments",value:e?.summary?.comments||0,of:0},{id:"redirects",label:"Redirects",value:e?.summary?.redirects||0,of:0}].map(i=>({...i,sub:i.of&&i.of!==i.value?`of ${i.of}`:""}))}export function historyRow(e,t=o=>o){const o=e.summary||{},i=Object.values(o.kinds||{}).reduce((n,l)=>n+(l.created||0),0),a=Object.values(o.kinds||{}).reduce((n,l)=>n+(l.updated||0),0),s=[];return i&&s.push(`${i} made`),a&&s.push(`${a} updated`),o.redirects?.created&&s.push(`${o.redirects.created} redirect${o.redirects.created===1?"":"s"}`),o.rebuild&&s.push(`${o.rebuild} to rebuild`),o.failed&&s.push(`${o.failed} failed`),e.status==="failed"&&s.splice(0,s.length,"Stopped before the end - run it again to finish"),{id:e.id,title:e.siteTitle||e.source||"WordPress site",meta:[t(e.at),e.by,e.file].filter(Boolean).join(" \xB7 "),summary:s.join(", ")||"Nothing changed",pill:e.status==="failed"?"Stopped":e.status==="partial"?"Some failed":"Done",pillClass:e.status==="failed"||e.status==="partial"?"is-bad":"is-ok"}}export function stagedRow(e,t=o=>o){const o=e.counts||{},i=[o.page&&`${o.page} pages`,o.post&&`${o.post} posts`,o.product&&`${o.product} products`,o.attachment&&`${o.attachment} media`].filter(Boolean);return{id:e.id,title:e.siteTitle||e.fileName||"WordPress export",meta:[e.fileName,t(e.at),i.join(", ")].filter(Boolean).join(" \xB7 "),pill:e.uploads?"Uploads zip added":"Waiting",pillClass:e.uploads?"is-ok":"is-muted"}}export function productSummary(e){const t=e?.summary?.products;if(!t?.total)return null;const o=t.shop||e.shop||{},i=e.options?.products!==!1,a=Object.entries(t.types||{}).map(([d,u])=>`${u} ${(PRODUCT_TYPE_LABEL[d]||d).toLowerCase()}`).join(", "),s=e.summary.counts?.product||{},n=[{label:"In the export",value:`${t.total}${a?` (${a})`:""}`}];o.available&&i&&(n.push({label:"On sale in the Shop",value:String(t.onSale||0)}),n.push({label:"As drafts",value:String(t.drafts||0)}),s.keep&&n.push({label:"Left as is",value:String(s.keep)}),n.push({label:"Skipped",value:String(s.skip||0)})),t.rebuild&&n.push({label:"Need rebuilding",value:String(t.rebuild)});let l,r="info";return o.available?i?l=`Products go to the Shop at ${o.basePath||"/shop"}.`:l='Products are not being imported - switch on "WooCommerce products" above to bring them in.':(l=o.reason||"Switch on the Shop to bring these in.",r="warn"),{note:l,tone:r,rows:n,notes:Array.isArray(t.notes)?t.notes:[]}}
@@ -101,7 +101,9 @@
101
101
  <label class="wpx-toggle"><input type="checkbox" class="form-switch" data-model="optRedirects.value"> Redirects from the old addresses
102
102
  <span data-help-title="Redirects" data-help="Links and search results that point at the old addresses keep working: each old page, post, category and tag address answers with a permanent (301) redirect to its new one, in SEO › Redirects. ?p=123 and ?page_id=45 addresses are answered too. An address a page on this site already uses is never redirected."></span></label>
103
103
  <label class="wpx-toggle"><input type="checkbox" class="form-switch" data-model="optDrafts.value"> Drafts and private items
104
- <span data-help="Drafts, pending, private and password-protected pages and posts - imported as drafts, so nobody sees them until you publish them. Items in the WordPress bin are never imported."></span></label>
104
+ <span data-help="Drafts, pending, private and password-protected pages, posts and products - imported as drafts, so nobody sees them until you publish them. Items in the WordPress bin are never imported."></span></label>
105
+ <label class="wpx-toggle" hidden data-bind-hidden="!hasProducts.value"><input type="checkbox" class="form-switch" data-model="optProducts.value" data-bind-disabled="!shopAvailable.value"> WooCommerce products
106
+ <span data-help-title="WooCommerce products" data-help="Each product goes to the Shop with its price (and sale price, as the &quot;was&quot; price), SKU, stock, weight, pictures and category; a product with options (colour, size…) keeps them, each with its own price, SKU and stock. Published products go on sale; drafts, private and hidden ones arrive as drafts. Grouped products are listed to rebuild (their products come across on their own); external products arrive as drafts with a link to where they were sold. Run it again and a product you changed in the Shop is left alone unless you choose Overwrite; stock is never reset, since sales here move it. Needs the Shop switched on."></span></label>
105
107
  </div>
106
108
  </div>
107
109
  </div>
@@ -115,9 +117,19 @@
115
117
  <div class="wpx-note-list" data-each="notes.value key=text"></div>
116
118
  </div>
117
119
 
120
+ <div class="wpx-card wpx-products" hidden data-bind-hidden="!hasProducts.value">
121
+ <div class="wpx-card-title"><span data-icon="shopping-bag" data-icon-size="16"></span> Products
122
+ <span data-help-title="WooCommerce products" data-help="What the export's WooCommerce products come to here. The currency is not in a WordPress export: prices are read as the Shop's own currency. Weights are read as kilograms, WooCommerce's usual unit. Orders, customers, coupons, reviews and tax and shipping settings never come across - they hold people's personal details, or settings a person should check; set tax and delivery in the Shop's settings. Product reviews may come across in a later version."></span>
123
+ <span class="wpx-spacer"></span>
124
+ <button type="button" class="btn btn-sm btn-ghost" data-on-click="showProducts">Show the products</button></div>
125
+ <p class="wpx-alert" data-bind-class="productNoteCls.value"><span data-bind-text="productNote.value"></span></p>
126
+ <dl class="wpx-facts" data-each="productFacts.value key=id"></dl>
127
+ <ul class="wpx-note wpx-product-notes" data-each="productNotes.value key=text"></ul>
128
+ </div>
129
+
118
130
  <div class="wpx-card">
119
131
  <div class="wpx-card-title">Item by item
120
- <span data-help-title="Item by item" data-help="What happens to each page, post, file and menu. New: made here. Renamed: its address is taken here, so it gets the next free one (the old address redirects to it). Update: made by an earlier import and unchanged here since - refreshed. Left as is: made by an earlier import but edited here since - not touched unless you choose Overwrite. Right-click (or ⋮, or Shift+F10) an item to skip it or change what happens. Needs rebuilding: shortcodes and page builders this site has no equivalent for - the text stays, the layout is yours to rebuild."></span>
132
+ <span data-help-title="Item by item" data-help="What happens to each page, post, product, file and menu. New: made here. Renamed: its address is taken here, so it gets the next free one (the old address redirects to it). Update: made by an earlier import and unchanged here since - refreshed. Left as is: made by an earlier import but edited here since - not touched unless you choose Overwrite. Right-click (or ⋮, or Shift+F10) an item to skip it or change what happens. Needs rebuilding: shortcodes and page builders this site has no equivalent for - the text stays, the layout is yours to rebuild."></span>
121
133
  <span class="wpx-spacer"></span>
122
134
  <small class="wpx-note" hidden data-bind-hidden="!refreshing.value">Updating…</small></div>
123
135
  <div class="wpx-bar-row">
@@ -159,6 +171,12 @@
159
171
  .wpx-alert { margin: 0; display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; padding: .6rem .8rem; border-radius: var(--dm-radius-md);
160
172
  background: color-mix(in srgb, var(--dm-warning) 16%, transparent); color: var(--dm-text); }
161
173
  .wpx-alert.is-bad { background: color-mix(in srgb, var(--dm-danger) 14%, transparent); color: var(--dm-danger); }
174
+ .wpx-alert.is-info { background: color-mix(in srgb, var(--dm-info, var(--dm-primary)) 12%, transparent); }
175
+ .wpx-facts { margin: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); gap: .4rem .9rem; }
176
+ .wpx-product-notes { padding-left: 1.1rem; display: flex; flex-direction: column; gap: .25rem; }
177
+ .wpx-fact { display: flex; flex-direction: column; min-width: 0; }
178
+ .wpx-fact dt { color: var(--dm-text-muted); font-size: var(--dm-text-xs); }
179
+ .wpx-fact dd { margin: 0; font-weight: 600; overflow-wrap: anywhere; }
162
180
  .wpx-alert.is-dirty { background: color-mix(in srgb, var(--dm-primary) 12%, transparent); }
163
181
  .wpx-spacer { flex: 1; }
164
182
  .wpx-card { border: 1px solid var(--dm-border); border-radius: var(--dm-radius-md); padding: .75rem .9rem; display: flex; flex-direction: column; gap: .65rem; background: var(--dm-surface); }
@@ -1,9 +1,9 @@
1
- import{apiRequest as q,getToken as Wt}from"../api.js";import{addBannerAction as Zt}from"../lib/plugin-chrome.js";import{helpPopovers as Fe}from"../lib/help-popover.js";import{onceClosed as Jt,openMenuAt as J,sidebarCount as C,viewLifetime as Vt}from"../lib/tool-kit.js";import{SHAPES as Ke,whileLoading as We}from"../lib/loading.js";import{fmtDateTime as Gt}from"../lib/dates.js";import{applyChoice as Xt,choiceItems as Yt,cleanOptions as pe,counts as Ze,defaultOptions as Se,draftKey as Qt,draftQuestion as ea,historyRow as ta,isDirty as aa,kindTabs as oa,liveDrafts as Je,optionsSnapshot as Ve,PLAN_FILTERS as Ge,planMatches as Xe,planRow as sa,planTiles as Ye,progressPercent as na,progressText as ra,REPORT_FILTERS as Qe,reportMatches as et,reportRow as ia,stagedRow as la,withDraft as tt}from"../lib/wordpress-import-arrange.js";const at=/^#\/wordpress-import\/?(\?.*)?$/,V="#/wordpress-import",T="/import/wordpress",de=400,ca=`
1
+ import{apiRequest as q,getToken as ea}from"../api.js";import{addBannerAction as ta}from"../lib/plugin-chrome.js";import{helpPopovers as We}from"../lib/help-popover.js";import{onceClosed as aa,openMenuAt as X,sidebarCount as R,viewLifetime as oa}from"../lib/tool-kit.js";import{SHAPES as Ze,whileLoading as Ve}from"../lib/loading.js";import{fmtDateTime as sa}from"../lib/dates.js";import{applyChoice as na,choiceItems as ra,cleanOptions as ue,counts as Je,defaultOptions as Le,draftKey as ia,draftQuestion as la,historyRow as ca,isDirty as pa,kindTabs as da,liveDrafts as Ge,optionsSnapshot as Xe,PLAN_FILTERS as Ye,planMatches as Qe,planRow as ua,planTiles as et,productSummary as ma,progressPercent as fa,progressText as va,REPORT_FILTERS as tt,reportMatches as at,reportRow as ha,stagedRow as wa,withDraft as ot}from"../lib/wordpress-import-arrange.js";const st=/^#\/wordpress-import\/?(\?.*)?$/,Y="#/wordpress-import",$="/import/wordpress",me=400,ba=`
2
2
  <div class="wpx-row" data-id="{{id}}" tabindex="0">
3
3
  <span class="wpx-main"><strong>{{title}}</strong><small>{{meta}}</small></span>
4
4
  <span class="wpx-chips"><span class="wpx-chip" data-bind-class="pillClass">{{pill}}</span></span>
5
5
  <button type="button" class="wpx-kebab" aria-label="Actions for {{title}}" title="Actions">\u22EE</button>
6
- </div>`,ot=`
6
+ </div>`,nt=`
7
7
  <div class="wpx-row" data-key="{{key}}" tabindex="0">
8
8
  <span class="wpx-main">
9
9
  <strong>{{title}}</strong>
@@ -14,17 +14,17 @@ import{apiRequest as q,getToken as Wt}from"../api.js";import{addBannerAction as
14
14
  </span>
15
15
  <span class="wpx-chips"><span class="wpx-chip" data-bind-class="pillCls">{{pill}}</span></span>
16
16
  <button type="button" class="wpx-kebab" aria-label="Actions for {{title}}" title="Actions">\u22EE</button>
17
- </div>`,st=`
17
+ </div>`,rt=`
18
18
  <div class="wpx-row" data-from="{{from}}" tabindex="0">
19
19
  <span class="wpx-main"><span class="wpx-where">{{from}} \u2192 {{to}}</span><span class="wpx-reason" data-bind-hidden="!reason">{{reason}}</span></span>
20
20
  <span class="wpx-chips"><span class="wpx-chip" data-bind-class="pillClass">{{pill}}</span></span>
21
21
  <button type="button" class="wpx-kebab" aria-label="Actions for {{from}}" title="Actions">\u22EE</button>
22
- </div>`,pa=`
22
+ </div>`,ga=`
23
23
  <div class="wpx-row" data-id="{{id}}" tabindex="0">
24
24
  <span class="wpx-main"><strong>{{title}}</strong><small>{{meta}}</small><span class="wpx-reason">{{summary}}</span></span>
25
25
  <span class="wpx-chips"><span class="wpx-chip" data-bind-class="pillClass">{{pill}}</span></span>
26
26
  <button type="button" class="wpx-kebab" aria-label="Actions for {{title}}" title="Actions">\u22EE</button>
27
- </div>`,nt='<div class="wpx-tile"><strong>{{value}}</strong><small>{{label}} <span data-bind-hidden="!sub">{{sub}}</span></small></div>',rt='<p class="wpx-alert"><span>{{text}}</span></p>',Le='<button type="button" data-on-click="$root.pickSeg($data)" data-bind-class="cls">{{label}} <b>{{count}}</b></button>',y=Vt(at);function it(l,n,r){return new Promise((w,g)=>{const c=new XMLHttpRequest,L=new FormData;L.append("file",n),c.open("POST",`/api${l}`);const v=Wt();v&&c.setRequestHeader("Authorization",`Bearer ${v}`),c.upload.onprogress=p=>{p.lengthComputable&&r(p.loaded/p.total)},c.onload=()=>{let p=null;try{p=JSON.parse(c.responseText)}catch{}c.status>=200&&c.status<300?w(p):g(new Error(p?.error||`The upload failed (${c.status}).`))},c.onerror=()=>g(new Error("The upload failed - the connection dropped.")),c.send(L),y.add(()=>{c.readyState!==4&&c.abort()})})}const ue=l=>l>=1048576?`${Math.round(l/1048576)} MB`:`${Math.max(1,Math.round(l/1024))} KB`,H=l=>String(l??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;");function da(l){const n=document.createElement("template");return n.innerHTML=l.trim(),n.content.firstElementChild}async function me(l,n){const r=E.confirm(l,n);let w=null;try{w=[...document.querySelectorAll(".dm-dialog-overlay")].at(-1)??null}catch{}const g=y.add(()=>{if(!w)return;const c=w;w=null;try{c.querySelector(".dm-dialog-cancel")?.click(),c.remove()}catch{}});try{return await r}finally{w=null,g()}}function lt(l){navigator.clipboard?.writeText(l).then(()=>E.toast("Copied.",{type:"success"}),()=>E.toast(l,{type:"info",duration:8e3}))}function fe(l,n,r,w){const g=E.contextMenu(l,{cursor:"glyph",match:n,inherit:!1,density:"compact",items:r});y.add(()=>g?.destroy?.());const c=v=>{const p=v.target.closest(n);if(!p||!l.contains(p))return;const d=v.target.closest(".wpx-kebab");if(d){J(d);return}w?.(p)},L=v=>{const p=v.target.closest(n);p&&(v.key==="F10"&&v.shiftKey?(v.preventDefault(),J(p)):v.key==="Enter"&&v.target===p&&w&&(v.preventDefault(),v.stopPropagation(),w(p)))};l.addEventListener("click",c),l.addEventListener("keydown",L),y.add(()=>{l.removeEventListener("click",c),l.removeEventListener("keydown",L)})}export const wordpressImportView={templateUrl:"/admin/js/templates/wordpress-import.html",async onMount(l){y.reset();const n=l.get(0).querySelector(".wpx")||l.get(0),r=()=>at.test(location.hash)&&n.isConnected;let w="";try{w=S.get("auth_user")?.id||""}catch{}const g=Qt(w),c=()=>{try{return g?S.get(g):null}catch{return null}},L=e=>{try{g&&S.set(g,e)}catch{}},v=n.querySelector(".wpx-loading");let p;try{p=await We(v,q(`${T}/status`),Ke.rows)}catch(e){if(!n.isConnected)return;v&&(v.hidden=!0);const t=n.querySelector(".wpx-failed");t&&(t.textContent=`Could not load the importer: ${e.message||e}. Reload the page to try again.`,t.hidden=!1);return}if(!r())return;v&&(v.hidden=!0),n.querySelector(".wpx-body").hidden=!1;const d=M.observable(p.staged||[]),P=M.observable(p.history||[]),N=M.observable(p.blog||{available:!1}),z=p.limits||{},b=M.observable(p.running||null),u=M.observable(""),k=M.observable(null),G=M.observable(!1),ve=M.observable(!1),he=M.observable(""),h=M.observable(Se(N.peek().available)),X=M.observable("all"),D=M.observable(""),we=M.observable(""),Y=M.observable(""),j=M.observable(""),Q=M.observable(""),ee=M.observable(!1);let te=!0;const ua=()=>d.peek().find(e=>e.id===u.peek())||null,be=M.computed(()=>d.value.find(e=>e.id===u.value)||null),ct=M.computed(()=>u.value?"preview":"start"),R=M.computed(()=>!!N.value.available),qe=M.computed(()=>!!u.value&&aa(h.value,R.value)),ae=e=>M.computed({read:()=>h.value[e]!==!1,write:t=>{h.value={...h.peek(),[e]:!!t}}}),A=e=>{h.value={...h.peek(),...e}},_=e=>{try{return Gt(e)}catch{return e}},pt=M.computed(()=>d.value.map(e=>la(e,_))),dt=M.computed(()=>P.value.map(e=>ta(e,_))),B=M.computed(()=>(k.value?.items||[]).map(e=>({...e,choice:h.value.choices?.[e.key]}))),ut=M.computed(()=>oa(B.value).map(e=>({...e,cls:D.value===e.id?"is-on":"",seg:"kind"}))),mt=M.computed(()=>Ze(B.value,Ge,Xe,D.value)),ft=M.computed(()=>Ge.map(e=>({...e,count:mt.value[e.id],cls:X.value===e.id?"is-on":"",seg:"filter"}))),ge=M.computed(()=>{const e=we.value.trim().toLowerCase();return B.value.filter(t=>(!D.value||t.kind===D.value)&&Xe(t,X.value)&&(!e||`${t.title} ${t.target} ${t.oldUrl}`.toLowerCase().includes(e)))}),vt=M.computed(()=>ge.value.slice(0,de).map(e=>{const t=sa(e);return{...t,pillCls:`${t.pillClass}${e.choice?" is-chosen":""}`}})),ht=M.computed(()=>ge.value.length>de?`Showing the first ${de} of ${ge.value.length} - search or filter to find the rest.`:""),wt=M.computed(()=>B.value.length?"Nothing matches.":"This export has nothing to import."),bt=M.computed(()=>Ye(k.value)),gt=M.computed(()=>(k.value?.notes||[]).map(e=>({text:e}))),yt=M.computed(()=>(k.value?.redirects||[]).slice(0,de).map(e=>({...e,pill:e.action==="skip"?"Skipped":e.action==="update"?"Update":"New",pillClass:e.action==="skip"?"is-muted":"is-ok"}))),kt=M.computed(()=>String((k.value?.redirects||[]).filter(e=>e.action!=="skip").length)),xt=M.computed(()=>k.value?.site?.title||be.value?.siteTitle||"WordPress export"),Mt=M.computed(()=>{const e=be.value,t=k.value?.site;return[t?.url||e?.siteUrl,e?.fileName,t?.wxrVersion&&`WXR ${t.wxrVersion}`,e?.at&&`uploaded ${_(e.at)}`].filter(Boolean).join(" \xB7 ")}),Tt=M.computed(()=>R.value?`Posts go to ${N.value.basePath||"/blog"}.`:N.value.reason||"No Blog is switched on here."),oe=M.computed(()=>be.value?.uploads||null),Et=M.computed(()=>{const e=oe.value;return e?`${e.fileName} - ${e.files} file${e.files===1?"":"s"}, ${ue(e.size)}${e.unsafe?`. ${e.unsafe} with unsafe names (like ../) were ignored`:""}.`:`Zip the wp-content/uploads folder and upload it here (up to ${ue(z.uploads||0)}).`}),$t=M.computed(()=>oe.value?"Replace the zip":"Upload the uploads zip"),Re=M.computed(()=>!!k.value&&!b.value&&!G.value&&!(h.value.media==="zip"&&!oe.value)),St=M.computed(()=>b.value?`Importing${b.value.siteTitle?` ${b.value.siteTitle}`:""}\u2026`:""),Lt=M.computed(()=>ra(b.value)),Ce=M.computed(()=>na(b.value)),qt=M.observable(ue(z.wxr||0)),Pe=n.querySelector(".wpx-running .wpx-bar-fill");y.add(M.effect(()=>{Pe&&(Pe.style.width=`${Ce.value}%`)}));async function ye(){const e=await q(`${T}/status`);return r()?(d.value=e.staged||[],P.value=e.history||[],N.value=e.blog||{available:!1},e.running&&!b.peek()&&(b.value=e.running,K()),e):null}let se=0,ke=null;async function ne({first:e=!1}={}){const t=u.peek();if(!t)return;const a=++se;he.value="";const s=q(`${T}/staged/${t}/preview`,{method:"POST",body:JSON.stringify({options:pe(h.peek(),R.peek())})});try{let f;if(e?(G.value=!0,f=await We(n.querySelector(".wpx-plan-loading"),s,Ke.table)):(ve.value=!0,f=await s),a!==se||!r()||u.peek()!==t)return;k.value=f.plan}catch(f){if(a!==se||!r())return;if(f.status===404){E.toast("That upload has gone - upload the export again.",{type:"warning"}),F(),ye().catch(()=>{});return}he.value=`Could not read the export: ${f.message||f}`}finally{a===se&&(G.value=!1,ve.value=!1)}}let re="";y.add(M.effect(()=>{const e=`${u.value}|${Ve(h.value)}`;if(e===re)return;const t=re.split("|")[0];re=e,!(!u.value||t!==u.value)&&(clearTimeout(ke),ke=setTimeout(()=>ne(),250))})),y.add(()=>clearTimeout(ke)),y.add(M.effect(()=>{const e=u.value,t=h.value,a=qe.value;if(!e||!te||!g)return;const s=c();L(tt(s,w,e,a?{options:pe(t,!0),at:new Date().toISOString(),was:e}:null))}));const xe=e=>{g&&L(tt(c(),w,e,null))};async function ie(e){if(!d.peek().some(m=>m.id===e))return;const t=d.peek().find(m=>m.id===e),a=Je(c(),d.peek().map(m=>m.id),w).items[e];if(te=!a,k.value=null,X.value="all",D.value="",we.value="",h.value=Se(R.peek()),re=`${e}|${Ve(h.peek())}`,u.value=e,await ne({first:!0}),!r()||u.peek()!==e||!a)return;await new Promise(m=>setTimeout(m,0));const s=ea({when:a.at?_(a.at):"",file:t?.fileName||""}),f=await me(H(s.text),{title:s.title,confirmText:s.confirmText,cancelText:s.cancelText});!r()||u.peek()!==e||(te=!0,f?xe(e):h.value=pe(a.options,R.peek()))}function F(){u.value="",k.value=null,te=!0}async function De(e=u.peek()){const t=d.peek().find(a=>a.id===e);if(t&&await me(`Discard the upload of <strong>${H(t.siteTitle||t.fileName)}</strong>? Nothing has been imported from it.`,{title:"Discard upload",confirmText:"Discard",danger:!0}))try{if(await q(`${T}/staged/${e}`,{method:"DELETE"}),xe(e),!r())return;u.peek()===e&&F(),d.value=d.peek().filter(a=>a.id!==e),C(V)}catch(a){E.toast(`Not discarded: ${a.message||a}`,{type:"error"})}}async function Ae(e){if(!e)return;if(j.value="",!/\.(xml|zip)$/i.test(e.name)){j.value="Upload the .xml file WordPress exports, or a .zip holding it.";return}if(z.wxr&&e.size>z.wxr*1.2&&/\.xml$/i.test(e.name)){j.value=`That file is over ${ue(z.wxr)}.`;return}const t=n.querySelector(".wpx-start .wpx-upload .wpx-bar-fill");Y.value=`Uploading ${e.name}\u2026`;try{const a=await it(`${T}/upload`,e,s=>{t&&(t.style.width=`${Math.round(s*100)}%`),Y.value=s<1?`Uploading ${e.name} - ${Math.round(s*100)}%`:`Reading ${e.name}\u2026`});if(!r())return;d.value=[a,...d.peek().filter(s=>s.id!==a.id)],C(V),await ie(a.id)}catch(a){r()&&(j.value=a.message||String(a))}finally{r()&&(Y.value="",t&&(t.style.width="0"))}}async function Rt(e){const t=u.peek();if(!e||!t)return;if(!/\.zip$/i.test(e.name)){E.toast("Zip the wp-content/uploads folder and upload the .zip.",{type:"warning"});return}const a=n.querySelector(".wpx-zip-fill");Q.value=`Uploading ${e.name}\u2026`;try{const s=await it(`${T}/staged/${t}/uploads`,e,f=>{a&&(a.style.width=`${Math.round(f*100)}%`),Q.value=f<1?`Uploading ${e.name} - ${Math.round(f*100)}%`:`Checking ${e.name}\u2026`});if(!r())return;d.value=d.peek().map(f=>f.id===s.id?s:f),u.peek()===t&&ne()}catch(s){r()&&E.toast(s.message||String(s),{type:"error"})}finally{r()&&(Q.value="",a&&(a.style.width="0"))}}async function Ct(){const e=u.peek();try{const t=await q(`${T}/staged/${e}/uploads`,{method:"DELETE"});if(!r())return;d.value=d.peek().map(a=>a.id===t.id?t:a),ne()}catch(t){E.toast(`Not removed: ${t.message||t}`,{type:"error"})}}async function Pt(){const e=u.peek(),t=k.peek();if(!e||!t||!Re.peek())return;const s=Ye(t).filter(m=>m.value&&m.id!=="comments").map(m=>`${m.value} ${m.label.toLowerCase()}`);if(!(!await me(`Import <strong>${H(t.site?.title||"this export")}</strong>: ${H(s.join(", ")||"nothing new")}? Pages edited here since an earlier import are left alone unless you chose Overwrite.`,{title:"Run the import",confirmText:"Run import"})||!r()||u.peek()!==e))try{const m=await q(`${T}/staged/${e}/run`,{method:"POST",body:JSON.stringify({options:pe(h.peek(),R.peek())})});if(xe(e),!r())return;b.value={...m.job,siteTitle:t.site?.title||""},F(),C(V),K()}catch(m){E.toast(`The import did not start: ${m.message||m}`,{type:"error"})}}let Me=null;function K(){clearTimeout(Me);const e=b.peek();e&&(Me=setTimeout(async()=>{try{const t=await q(`${T}/jobs/${e.id}`);if(!r())return;if(b.value={...t.job,siteTitle:e.siteTitle},t.job.status==="running")return K();if(b.value=null,await ye().catch(()=>{}),C(V),C("#/pages"),C("#/media"),!r())return;t.job.status==="done"?(E.toast("The import has finished - here is its report.",{type:"success"}),le(t.job.reportId)):(E.toast(`The import stopped: ${t.job.error||"an error"}`,{type:"error"}),t.job.reportId&&le(t.job.reportId))}catch(t){if(!r())return;if(t.status===404){b.value=null,ye().catch(()=>{});return}K()}},700))}y.add(()=>clearTimeout(Me)),b.peek()&&K();let O=!1;async function le(e){if(O||!e)return;O=!0;let t;try{t=await q(`${T}/history/${e}`)}catch(o){O=!1,E.toast(`Could not open the report: ${o.message||o}`,{type:"error"});return}if(!r()){O=!1;return}let a;try{a=E.slideover({title:H(`Report - ${t.run?.siteTitle||"WordPress import"}`),size:"lg",position:"right"})}catch(o){throw O=!1,o}const s=da(`
27
+ </div>`,it='<div class="wpx-tile"><strong>{{value}}</strong><small>{{label}} <span data-bind-hidden="!sub">{{sub}}</span></small></div>',lt='<p class="wpx-alert"><span>{{text}}</span></p>',ya="<li>{{text}}</li>",xa='<div class="wpx-fact"><dt>{{label}}</dt><dd>{{value}}</dd></div>',qe='<button type="button" data-on-click="$root.pickSeg($data)" data-bind-class="cls">{{label}} <b>{{count}}</b></button>',x=oa(st);function ct(l,n,i){return new Promise((w,y)=>{const p=new XMLHttpRequest,L=new FormData;L.append("file",n),p.open("POST",`/api${l}`);const v=ea();v&&p.setRequestHeader("Authorization",`Bearer ${v}`),p.upload.onprogress=c=>{c.lengthComputable&&i(c.loaded/c.total)},p.onload=()=>{let c=null;try{c=JSON.parse(p.responseText)}catch{}p.status>=200&&p.status<300?w(c):y(new Error(c?.error||`The upload failed (${p.status}).`))},p.onerror=()=>y(new Error("The upload failed - the connection dropped.")),p.send(L),x.add(()=>{p.readyState!==4&&p.abort()})})}const fe=l=>l>=1048576?`${Math.round(l/1048576)} MB`:`${Math.max(1,Math.round(l/1024))} KB`,N=l=>String(l??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;");function ka(l){const n=document.createElement("template");return n.innerHTML=l.trim(),n.content.firstElementChild}async function ve(l,n){const i=E.confirm(l,n);let w=null;try{w=[...document.querySelectorAll(".dm-dialog-overlay")].at(-1)??null}catch{}const y=x.add(()=>{if(!w)return;const p=w;w=null;try{p.querySelector(".dm-dialog-cancel")?.click(),p.remove()}catch{}});try{return await i}finally{w=null,y()}}function pt(l){navigator.clipboard?.writeText(l).then(()=>E.toast("Copied.",{type:"success"}),()=>E.toast(l,{type:"info",duration:8e3}))}function he(l,n,i,w){const y=E.contextMenu(l,{cursor:"glyph",match:n,inherit:!1,density:"compact",items:i});x.add(()=>y?.destroy?.());const p=v=>{const c=v.target.closest(n);if(!c||!l.contains(c))return;const d=v.target.closest(".wpx-kebab");if(d){X(d);return}w?.(c)},L=v=>{const c=v.target.closest(n);c&&(v.key==="F10"&&v.shiftKey?(v.preventDefault(),X(c)):v.key==="Enter"&&v.target===c&&w&&(v.preventDefault(),v.stopPropagation(),w(c)))};l.addEventListener("click",p),l.addEventListener("keydown",L),x.add(()=>{l.removeEventListener("click",p),l.removeEventListener("keydown",L)})}export const wordpressImportView={templateUrl:"/admin/js/templates/wordpress-import.html",async onMount(l){x.reset();const n=l.get(0).querySelector(".wpx")||l.get(0),i=()=>st.test(location.hash)&&n.isConnected;let w="";try{w=S.get("auth_user")?.id||""}catch{}const y=ia(w),p=()=>{try{return y?S.get(y):null}catch{return null}},L=e=>{try{y&&S.set(y,e)}catch{}},v=n.querySelector(".wpx-loading");let c;try{c=await Ve(v,q(`${$}/status`),Ze.rows)}catch(e){if(!n.isConnected)return;v&&(v.hidden=!0);const t=n.querySelector(".wpx-failed");t&&(t.textContent=`Could not load the importer: ${e.message||e}. Reload the page to try again.`,t.hidden=!1);return}if(!i())return;v&&(v.hidden=!0),n.querySelector(".wpx-body").hidden=!1;const d=M.observable(c.staged||[]),A=M.observable(c.history||[]),H=M.observable(c.blog||{available:!1}),Ce=M.observable(c.shop||{available:!1}),_=c.limits||{},b=M.observable(c.running||null),u=M.observable(""),g=M.observable(null),Q=M.observable(!1),we=M.observable(!1),be=M.observable(""),h=M.observable(Le(H.peek().available)),z=M.observable("all"),P=M.observable(""),ee=M.observable(""),te=M.observable(""),j=M.observable(""),ae=M.observable(""),oe=M.observable(!1);let se=!0;const Ma=()=>d.peek().find(e=>e.id===u.peek())||null,ge=M.computed(()=>d.value.find(e=>e.id===u.value)||null),dt=M.computed(()=>u.value?"preview":"start"),C=M.computed(()=>!!H.value.available),ut=M.computed(()=>!!(g.value?.shop||Ce.value).available),Re=M.computed(()=>!!u.value&&pa(h.value,C.value)),B=e=>M.computed({read:()=>h.value[e]!==!1,write:t=>{h.value={...h.peek(),[e]:!!t}}}),D=e=>{h.value={...h.peek(),...e}},F=e=>{try{return sa(e)}catch{return e}},mt=M.computed(()=>d.value.map(e=>wa(e,F))),ft=M.computed(()=>A.value.map(e=>ca(e,F))),K=M.computed(()=>(g.value?.items||[]).map(e=>({...e,choice:h.value.choices?.[e.key]}))),vt=M.computed(()=>da(K.value).map(e=>({...e,cls:P.value===e.id?"is-on":"",seg:"kind"}))),ht=M.computed(()=>Je(K.value,Ye,Qe,P.value)),wt=M.computed(()=>Ye.map(e=>({...e,count:ht.value[e.id],cls:z.value===e.id?"is-on":"",seg:"filter"}))),ye=M.computed(()=>{const e=ee.value.trim().toLowerCase();return K.value.filter(t=>(!P.value||t.kind===P.value)&&Qe(t,z.value)&&(!e||`${t.title} ${t.target} ${t.oldUrl}`.toLowerCase().includes(e)))}),bt=M.computed(()=>ye.value.slice(0,me).map(e=>{const t=ua(e);return{...t,pillCls:`${t.pillClass}${e.choice?" is-chosen":""}`}})),gt=M.computed(()=>ye.value.length>me?`Showing the first ${me} of ${ye.value.length} - search or filter to find the rest.`:""),yt=M.computed(()=>K.value.length?"Nothing matches.":"This export has nothing to import."),xt=M.computed(()=>et(g.value)),kt=M.computed(()=>(g.value?.notes||[]).map(e=>({text:e}))),Mt=M.computed(()=>(g.value?.redirects||[]).slice(0,me).map(e=>({...e,pill:e.action==="skip"?"Skipped":e.action==="update"?"Update":"New",pillClass:e.action==="skip"?"is-muted":"is-ok"}))),Tt=M.computed(()=>String((g.value?.redirects||[]).filter(e=>e.action!=="skip").length)),Et=M.computed(()=>g.value?.site?.title||ge.value?.siteTitle||"WordPress export"),$t=M.computed(()=>{const e=ge.value,t=g.value?.site;return[t?.url||e?.siteUrl,e?.fileName,t?.wxrVersion&&`WXR ${t.wxrVersion}`,e?.at&&`uploaded ${F(e.at)}`].filter(Boolean).join(" \xB7 ")}),W=M.computed(()=>ma(g.value)),St=M.computed(()=>W.value?.note||""),Lt=M.computed(()=>W.value?.tone==="warn"?"is-warn":"is-info"),qt=M.computed(()=>(W.value?.rows||[]).map(e=>({...e,id:e.label}))),Ct=M.computed(()=>(W.value?.notes||[]).map(e=>({text:e}))),Rt=M.computed(()=>!!W.value),Pt=M.computed(()=>C.value?`Posts go to ${H.value.basePath||"/blog"}.`:H.value.reason||"No Blog is switched on here."),ne=M.computed(()=>ge.value?.uploads||null),At=M.computed(()=>{const e=ne.value;return e?`${e.fileName} - ${e.files} file${e.files===1?"":"s"}, ${fe(e.size)}${e.unsafe?`. ${e.unsafe} with unsafe names (like ../) were ignored`:""}.`:`Zip the wp-content/uploads folder and upload it here (up to ${fe(_.uploads||0)}).`}),It=M.computed(()=>ne.value?"Replace the zip":"Upload the uploads zip"),Pe=M.computed(()=>!!g.value&&!b.value&&!Q.value&&!(h.value.media==="zip"&&!ne.value)),Dt=M.computed(()=>b.value?`Importing${b.value.siteTitle?` ${b.value.siteTitle}`:""}\u2026`:""),Ot=M.computed(()=>va(b.value)),Ae=M.computed(()=>fa(b.value)),Ut=M.observable(fe(_.wxr||0)),Ie=n.querySelector(".wpx-running .wpx-bar-fill");x.add(M.effect(()=>{Ie&&(Ie.style.width=`${Ae.value}%`)}));async function xe(){const e=await q(`${$}/status`);return i()?(d.value=e.staged||[],A.value=e.history||[],H.value=e.blog||{available:!1},Ce.value=e.shop||{available:!1},e.running&&!b.peek()&&(b.value=e.running,V()),e):null}let re=0,ke=null;async function ie({first:e=!1}={}){const t=u.peek();if(!t)return;const a=++re;be.value="";const s=q(`${$}/staged/${t}/preview`,{method:"POST",body:JSON.stringify({options:ue(h.peek(),C.peek())})});try{let f;if(e?(Q.value=!0,f=await Ve(n.querySelector(".wpx-plan-loading"),s,Ze.table)):(we.value=!0,f=await s),a!==re||!i()||u.peek()!==t)return;g.value=f.plan}catch(f){if(a!==re||!i())return;if(f.status===404){E.toast("That upload has gone - upload the export again.",{type:"warning"}),Z(),xe().catch(()=>{});return}be.value=`Could not read the export: ${f.message||f}`}finally{a===re&&(Q.value=!1,we.value=!1)}}let le="";x.add(M.effect(()=>{const e=`${u.value}|${Xe(h.value)}`;if(e===le)return;const t=le.split("|")[0];le=e,!(!u.value||t!==u.value)&&(clearTimeout(ke),ke=setTimeout(()=>ie(),250))})),x.add(()=>clearTimeout(ke)),x.add(M.effect(()=>{const e=u.value,t=h.value,a=Re.value;if(!e||!se||!y)return;const s=p();L(ot(s,w,e,a?{options:ue(t,!0),at:new Date().toISOString(),was:e}:null))}));const Me=e=>{y&&L(ot(p(),w,e,null))};async function ce(e){if(!d.peek().some(m=>m.id===e))return;const t=d.peek().find(m=>m.id===e),a=Ge(p(),d.peek().map(m=>m.id),w).items[e];if(se=!a,g.value=null,z.value="all",P.value="",ee.value="",h.value=Le(C.peek()),le=`${e}|${Xe(h.peek())}`,u.value=e,await ie({first:!0}),!i()||u.peek()!==e||!a)return;await new Promise(m=>setTimeout(m,0));const s=la({when:a.at?F(a.at):"",file:t?.fileName||""}),f=await ve(N(s.text),{title:s.title,confirmText:s.confirmText,cancelText:s.cancelText});!i()||u.peek()!==e||(se=!0,f?Me(e):h.value=ue(a.options,C.peek()))}function Z(){u.value="",g.value=null,se=!0}async function De(e=u.peek()){const t=d.peek().find(a=>a.id===e);if(t&&await ve(`Discard the upload of <strong>${N(t.siteTitle||t.fileName)}</strong>? Nothing has been imported from it.`,{title:"Discard upload",confirmText:"Discard",danger:!0}))try{if(await q(`${$}/staged/${e}`,{method:"DELETE"}),Me(e),!i())return;u.peek()===e&&Z(),d.value=d.peek().filter(a=>a.id!==e),R(Y)}catch(a){E.toast(`Not discarded: ${a.message||a}`,{type:"error"})}}async function Oe(e){if(!e)return;if(j.value="",!/\.(xml|zip)$/i.test(e.name)){j.value="Upload the .xml file WordPress exports, or a .zip holding it.";return}if(_.wxr&&e.size>_.wxr*1.2&&/\.xml$/i.test(e.name)){j.value=`That file is over ${fe(_.wxr)}.`;return}const t=n.querySelector(".wpx-start .wpx-upload .wpx-bar-fill");te.value=`Uploading ${e.name}\u2026`;try{const a=await ct(`${$}/upload`,e,s=>{t&&(t.style.width=`${Math.round(s*100)}%`),te.value=s<1?`Uploading ${e.name} - ${Math.round(s*100)}%`:`Reading ${e.name}\u2026`});if(!i())return;d.value=[a,...d.peek().filter(s=>s.id!==a.id)],R(Y),await ce(a.id)}catch(a){i()&&(j.value=a.message||String(a))}finally{i()&&(te.value="",t&&(t.style.width="0"))}}async function Nt(e){const t=u.peek();if(!e||!t)return;if(!/\.zip$/i.test(e.name)){E.toast("Zip the wp-content/uploads folder and upload the .zip.",{type:"warning"});return}const a=n.querySelector(".wpx-zip-fill");ae.value=`Uploading ${e.name}\u2026`;try{const s=await ct(`${$}/staged/${t}/uploads`,e,f=>{a&&(a.style.width=`${Math.round(f*100)}%`),ae.value=f<1?`Uploading ${e.name} - ${Math.round(f*100)}%`:`Checking ${e.name}\u2026`});if(!i())return;d.value=d.peek().map(f=>f.id===s.id?s:f),u.peek()===t&&ie()}catch(s){i()&&E.toast(s.message||String(s),{type:"error"})}finally{i()&&(ae.value="",a&&(a.style.width="0"))}}async function Ht(){const e=u.peek();try{const t=await q(`${$}/staged/${e}/uploads`,{method:"DELETE"});if(!i())return;d.value=d.peek().map(a=>a.id===t.id?t:a),ie()}catch(t){E.toast(`Not removed: ${t.message||t}`,{type:"error"})}}async function _t(){const e=u.peek(),t=g.peek();if(!e||!t||!Pe.peek())return;const s=et(t).filter(m=>m.value&&m.id!=="comments").map(m=>`${m.value} ${m.label.toLowerCase()}`);if(!(!await ve(`Import <strong>${N(t.site?.title||"this export")}</strong>: ${N(s.join(", ")||"nothing new")}? Pages edited here since an earlier import are left alone unless you chose Overwrite.`,{title:"Run the import",confirmText:"Run import"})||!i()||u.peek()!==e))try{const m=await q(`${$}/staged/${e}/run`,{method:"POST",body:JSON.stringify({options:ue(h.peek(),C.peek())})});if(Me(e),!i())return;b.value={...m.job,siteTitle:t.site?.title||""},Z(),R(Y),V()}catch(m){E.toast(`The import did not start: ${m.message||m}`,{type:"error"})}}let Te=null;function V(){clearTimeout(Te);const e=b.peek();e&&(Te=setTimeout(async()=>{try{const t=await q(`${$}/jobs/${e.id}`);if(!i())return;if(b.value={...t.job,siteTitle:e.siteTitle},t.job.status==="running")return V();if(b.value=null,await xe().catch(()=>{}),R(Y),R("#/pages"),R("#/media"),R("#/plugins/shopping-cart"),!i())return;t.job.status==="done"?(E.toast("The import has finished - here is its report.",{type:"success"}),pe(t.job.reportId)):(E.toast(`The import stopped: ${t.job.error||"an error"}`,{type:"error"}),t.job.reportId&&pe(t.job.reportId))}catch(t){if(!i())return;if(t.status===404){b.value=null,xe().catch(()=>{});return}V()}},700))}x.add(()=>clearTimeout(Te)),b.peek()&&V();let O=!1;async function pe(e){if(O||!e)return;O=!0;let t;try{t=await q(`${$}/history/${e}`)}catch(o){O=!1,E.toast(`Could not open the report: ${o.message||o}`,{type:"error"});return}if(!i()){O=!1;return}let a;try{a=E.slideover({title:N(`Report - ${t.run?.siteTitle||"WordPress import"}`),size:"lg",position:"right"})}catch(o){throw O=!1,o}const s=ka(`
28
28
  <div class="wpx wpx-report">
29
29
  <p class="wpx-note" data-bind-text="meta.value"></p>
30
30
  <div class="wpx-tiles" data-each="tiles.value key=id"></div>
@@ -35,4 +35,4 @@ import{apiRequest as q,getToken as Wt}from"../api.js";import{addBannerAction as
35
35
  <div class="wpx-list wpx-report-items" data-each="rows.value key=key"></div>
36
36
  <div class="wpx-card-title" data-bind-hidden="!redirects.value.length">Redirects</div>
37
37
  <div class="wpx-list wpx-report-redirects" data-each="redirects.value key=from"></div>
38
- </div>`);s.querySelector(".wpx-tiles").innerHTML=nt,s.querySelector(".wpx-note-list").innerHTML=rt,s.querySelector(".wpx-seg").innerHTML=Le,s.querySelector(".wpx-report-items").innerHTML=ot,s.querySelector(".wpx-report-redirects").innerHTML=st;const f=M.observable(t.run?.summary?.failed?"failed":"all"),m=t.items||[],je=Ze(m,Qe,et),Z=t.run?.summary||{},Ee=o=>Object.values(Z.kinds||{}).reduce((i,x)=>i+(x[o]||0),0),Ut={meta:M.observable([_(t.run?.at),t.run?.by,t.run?.file,t.run?.durationMs?`${Math.max(1,Math.round(t.run.durationMs/1e3))} s`:""].filter(Boolean).join(" \xB7 ")),tiles:M.observable([{id:"made",label:"Made",value:Ee("created"),sub:""},{id:"updated",label:"Updated",value:Ee("updated"),sub:""},{id:"kept",label:"Left as is",value:Ee("kept"),sub:""},{id:"redirects",label:"Redirects",value:(Z.redirects?.created||0)+(Z.redirects?.updated||0),sub:""},{id:"comments",label:"Comments",value:Z.comments||0,sub:""},{id:"failed",label:"Failed",value:Z.failed||0,sub:""}]),notes:M.observable((t.notes||[]).map(o=>({text:o}))),filters:M.computed(()=>Qe.filter(o=>o.id==="all"||je[o.id]).map(o=>({...o,count:je[o.id],cls:f.value===o.id?"is-on":""}))),rows:M.computed(()=>m.filter(o=>et(o,f.value)).slice(0,1e3).map(o=>{const i=ia(o);return{...i,pillCls:i.pillClass}})),redirects:M.observable((t.redirects||[]).filter(o=>o.result!=="skipped").slice(0,1e3).map(o=>({...o,reason:o.error||"",pill:o.result==="failed"?"Failed":o.result==="updated"?"Updated":"Added",pillClass:o.result==="failed"?"is-bad":"is-ok"})))};a.element.appendChild(s);const Ht=M.applyBindings(Ut,s,{methods:{pickSeg:o=>{f.value=o.id}}}),Nt=Fe(s),_e=new Map(m.map(o=>[o.key,o])),zt=s.querySelector(".wpx-report-items"),jt=o=>{const i=_e.get(o.dataset.key);if(!i)return[];const x=typeof i.target=="string"&&i.target.startsWith("/")?i.target:"",$=[{header:i.title}];return x&&i.result!=="failed"&&i.result!=="skipped"&&$.push({label:"Open on the site",icon:"external-link",action:()=>window.open(x,"_blank","noopener")}),x&&i.kind==="page"&&(i.result==="created"||i.result==="updated"||i.result==="kept")&&$.push({label:"Edit the page",icon:"edit",action:()=>{a.close(),location.hash=`#/pages/edit${x}`}}),/^https?:\/\//i.test(i.oldUrl)&&$.push({label:"Open the old address",icon:"link",action:()=>window.open(i.oldUrl,"_blank","noopener,noreferrer")}),x&&$.push({label:"Copy the new address",icon:"copy",action:()=>lt(new URL(x,location.origin).href)}),$},_t=E.contextMenu(zt,{cursor:"glyph",match:".wpx-row",inherit:!1,density:"compact",items:jt}),Bt=s.querySelector(".wpx-report-redirects"),Ft=E.contextMenu(Bt,{cursor:"glyph",match:".wpx-row",inherit:!1,density:"compact",items:o=>[{header:o.dataset.from},...o.dataset.from.includes("*")?[]:[{label:"Try it on the site",icon:"external-link",action:()=>window.open(o.dataset.from,"_blank","noopener")}],{label:"Open SEO \u203A Redirects",icon:"corner-up-right",action:()=>{a.close(),location.hash="#/seo/redirects"}}]}),$e=o=>{const i=o.target.closest(".wpx-kebab");if(i){J(i);return}const x=o.target.closest(".wpx-report-items .wpx-row");if(!x)return;const $=_e.get(x.dataset.key);$?.target?.startsWith("/")&&$.result!=="failed"&&$.result!=="skipped"&&window.open($.target,"_blank","noopener")},Be=o=>{const i=o.target.closest(".wpx-row");i&&(o.key==="F10"&&o.shiftKey?(o.preventDefault(),J(i)):o.key==="Enter"&&o.target===i&&(o.preventDefault(),o.stopPropagation(),$e({target:i})))};s.addEventListener("click",$e),s.addEventListener("keydown",Be);const Kt=y.add(()=>a.close());Jt(a,()=>{O=!1,Ht.dispose(),Nt(),_t?.destroy?.(),Ft?.destroy?.(),s.removeEventListener("click",$e),s.removeEventListener("keydown",Be),Kt()}),a.open(),I.scan(s)}async function Dt(e){const t=P.peek().find(a=>a.id===e);if(t&&await me(`Remove the import of <strong>${H(t.siteTitle||t.source)}</strong> from this list? Everything it imported stays on the site.`,{title:"Remove from the history",confirmText:"Remove"}))try{if(await q(`${T}/history/${e}`,{method:"DELETE"}),!r())return;P.value=P.peek().filter(a=>a.id!==e),C(V)}catch(a){E.toast(`Not removed: ${a.message||a}`,{type:"error"})}}n.querySelector(".wpx-staged").innerHTML=ca,n.querySelector(".wpx-items").innerHTML=ot,n.querySelector(".wpx-redirects").innerHTML=st,n.querySelector(".wpx-history").innerHTML=pa,n.querySelector(".wpx-tiles").innerHTML=nt,n.querySelector(".wpx-note-list").innerHTML=rt,n.querySelector(".wpx-kinds").innerHTML=Le,n.querySelector(".wpx-filters").innerHTML=Le;const At={mode:ct,job:b,jobTitle:St,jobText:Lt,jobPct:Ce,staged:d,stagedRows:pt,historyRows:dt,plan:k,planLoading:G,planError:he,refreshing:ve,opt:h,blogAvailable:R,blogNote:Tt,dirty:qe,canRun:Re,siteTitle:xt,siteMeta:Mt,tiles:bt,notes:gt,kinds:ut,filters:ft,rows:vt,moreText:ht,emptyText:wt,redirectRows:yt,redirectCount:kt,query:we,uploadText:Y,uploadError:j,dropping:ee,wxrLimit:qt,zipInfo:oe,zipText:Et,zipButton:$t,zipUploadText:Q,optComments:ae("comments"),optMenus:ae("menus"),optRedirects:ae("redirects"),optDrafts:ae("drafts")},It=M.applyBindings(At,n,{methods:{back:()=>F(),discard:()=>De(),run:()=>Pt(),resetChoices:()=>{h.value=Se(R.peek())},postsBlog:()=>A({posts:"blog"}),postsPages:()=>A({posts:"pages"}),postsSkip:()=>A({posts:"skip"}),mediaDownload:()=>A({media:"download"}),mediaZip:()=>A({media:"zip"}),mediaSkip:()=>A({media:"skip"}),removeZip:()=>Ct(),pickSeg:e=>{e.seg==="kind"?D.value=e.id:X.value=e.id}}});y.add(()=>It.dispose()),y.add(Fe(n,{position:"bottom"}));const W=n.querySelector(".wpx-file"),Ie=()=>{const e=W.files?.[0];W.value="",Ae(e)};W.addEventListener("change",Ie);const U=n.querySelector(".wpx-drop"),Oe=e=>{e.preventDefault(),ee.value=!0},Ue=()=>{ee.value=!1},He=e=>{e.preventDefault(),ee.value=!1,Ae(e.dataTransfer?.files?.[0])};U.addEventListener("dragover",Oe),U.addEventListener("dragleave",Ue),U.addEventListener("drop",He);const ce=n.querySelector(".wpx-zip-file"),Ne=()=>{const e=ce.files?.[0];ce.value="",Rt(e)};ce.addEventListener("change",Ne),y.add(()=>{W.removeEventListener("change",Ie),U.removeEventListener("dragover",Oe),U.removeEventListener("dragleave",Ue),U.removeEventListener("drop",He),ce.removeEventListener("change",Ne)}),fe(n.querySelector(".wpx-staged"),".wpx-row",e=>[{header:d.peek().find(t=>t.id===e.dataset.id)?.siteTitle||"Upload"},{label:"Preview the import",icon:"eye",action:()=>ie(e.dataset.id)},{label:"Discard the upload",icon:"trash-2",action:()=>De(e.dataset.id)}],e=>ie(e.dataset.id));const Ot=(e,t)=>{h.value={...h.peek(),choices:Xt(h.peek().choices,e,t)}};fe(n.querySelector(".wpx-items"),".wpx-row",e=>{const t=B.peek().find(s=>s.key===e.dataset.key);if(!t)return[];const a=[{header:t.title}];for(const s of Yt(t,t.choice))a.push({label:s.label,icon:s.icon,action:()=>Ot(t.key,s.id)});return t.oldUrl&&/^https?:\/\//i.test(t.oldUrl)&&a.push({label:"Open the old address",icon:"link",action:()=>window.open(t.oldUrl,"_blank","noopener,noreferrer")}),t.target?.startsWith("/")&&(t.action==="update"||t.action==="keep")&&a.push({label:"Open it on this site",icon:"external-link",action:()=>window.open(t.target,"_blank","noopener")}),a.length===1&&a.push({label:"Nothing to change here",icon:"info",disabled:!0,action:()=>{}}),a},e=>J(e.querySelector(".wpx-kebab")||e)),fe(n.querySelector(".wpx-redirects"),".wpx-row",e=>[{header:e.dataset.from},{label:"Copy the old address",icon:"copy",action:()=>lt(e.dataset.from)}],null),fe(n.querySelector(".wpx-history"),".wpx-row",e=>[{header:P.peek().find(t=>t.id===e.dataset.id)?.siteTitle||"Import"},{label:"Open the report",icon:"file-text",action:()=>le(e.dataset.id)},{label:"Remove from the history",icon:"trash-2",action:()=>Dt(e.dataset.id)}],e=>le(e.dataset.id)),Zt(l,{id:"wpx-upload",icon:"upload",title:"Upload an export",onClick:()=>{u.peek()&&F(),setTimeout(()=>W.click(),0)}}),I.scan(n);const Te=Je(c(),d.peek().map(e=>e.id),w);Te.pruned&&g&&L({owner:w,items:Te.items});const ze=Object.entries(Te.items).sort((e,t)=>String(t[1].at).localeCompare(String(e[1].at)))[0];ze&&!b.peek()&&await ie(ze[0])}};
38
+ </div>`);s.querySelector(".wpx-tiles").innerHTML=it,s.querySelector(".wpx-note-list").innerHTML=lt,s.querySelector(".wpx-seg").innerHTML=qe,s.querySelector(".wpx-report-items").innerHTML=nt,s.querySelector(".wpx-report-redirects").innerHTML=rt;const f=M.observable(t.run?.summary?.failed?"failed":"all"),m=t.items||[],Be=Je(m,tt,at),G=t.run?.summary||{},$e=o=>Object.values(G.kinds||{}).reduce((r,k)=>r+(k[o]||0),0),Kt={meta:M.observable([F(t.run?.at),t.run?.by,t.run?.file,t.run?.durationMs?`${Math.max(1,Math.round(t.run.durationMs/1e3))} s`:""].filter(Boolean).join(" \xB7 ")),tiles:M.observable([{id:"made",label:"Made",value:$e("created"),sub:""},{id:"updated",label:"Updated",value:$e("updated"),sub:""},{id:"kept",label:"Left as is",value:$e("kept"),sub:""},{id:"redirects",label:"Redirects",value:(G.redirects?.created||0)+(G.redirects?.updated||0),sub:""},{id:"comments",label:"Comments",value:G.comments||0,sub:""},{id:"failed",label:"Failed",value:G.failed||0,sub:""}]),notes:M.observable((t.notes||[]).map(o=>({text:o}))),filters:M.computed(()=>tt.filter(o=>o.id==="all"||Be[o.id]).map(o=>({...o,count:Be[o.id],cls:f.value===o.id?"is-on":""}))),rows:M.computed(()=>m.filter(o=>at(o,f.value)).slice(0,1e3).map(o=>{const r=ha(o);return{...r,pillCls:r.pillClass}})),redirects:M.observable((t.redirects||[]).filter(o=>o.result!=="skipped").slice(0,1e3).map(o=>({...o,reason:o.error||"",pill:o.result==="failed"?"Failed":o.result==="updated"?"Updated":"Added",pillClass:o.result==="failed"?"is-bad":"is-ok"})))};a.element.appendChild(s);const Wt=M.applyBindings(Kt,s,{methods:{pickSeg:o=>{f.value=o.id}}}),Zt=We(s),Fe=new Map(m.map(o=>[o.key,o])),Vt=s.querySelector(".wpx-report-items"),Jt=o=>{const r=Fe.get(o.dataset.key);if(!r)return[];const k=typeof r.target=="string"&&r.target.startsWith("/")?r.target:"",T=[{header:r.title}];return k&&r.result!=="failed"&&r.result!=="skipped"&&T.push({label:"Open on the site",icon:"external-link",action:()=>window.open(k,"_blank","noopener")}),k&&r.kind==="page"&&(r.result==="created"||r.result==="updated"||r.result==="kept")&&T.push({label:"Edit the page",icon:"edit",action:()=>{a.close(),location.hash=`#/pages/edit${k}`}}),r.kind==="product"&&r.entryId&&/^[\w-]{1,64}$/.test(r.entryId)&&T.push({label:"Edit in the Shop",icon:"shopping-bag",action:()=>{a.close(),location.hash=`#/plugins/shopping-cart/products/${encodeURIComponent(r.entryId)}`}}),/^https?:\/\//i.test(r.oldUrl)&&T.push({label:"Open the old address",icon:"link",action:()=>window.open(r.oldUrl,"_blank","noopener,noreferrer")}),k&&T.push({label:"Copy the new address",icon:"copy",action:()=>pt(new URL(k,location.origin).href)}),T},Gt=E.contextMenu(Vt,{cursor:"glyph",match:".wpx-row",inherit:!1,density:"compact",items:Jt}),Xt=s.querySelector(".wpx-report-redirects"),Yt=E.contextMenu(Xt,{cursor:"glyph",match:".wpx-row",inherit:!1,density:"compact",items:o=>[{header:o.dataset.from},...o.dataset.from.includes("*")?[]:[{label:"Try it on the site",icon:"external-link",action:()=>window.open(o.dataset.from,"_blank","noopener")}],{label:"Open SEO \u203A Redirects",icon:"corner-up-right",action:()=>{a.close(),location.hash="#/seo/redirects"}}]}),Se=o=>{const r=o.target.closest(".wpx-kebab");if(r){X(r);return}const k=o.target.closest(".wpx-report-items .wpx-row");if(!k)return;const T=Fe.get(k.dataset.key);T?.target?.startsWith("/")&&T.result!=="failed"&&T.result!=="skipped"&&window.open(T.target,"_blank","noopener")},Ke=o=>{const r=o.target.closest(".wpx-row");r&&(o.key==="F10"&&o.shiftKey?(o.preventDefault(),X(r)):o.key==="Enter"&&o.target===r&&(o.preventDefault(),o.stopPropagation(),Se({target:r})))};s.addEventListener("click",Se),s.addEventListener("keydown",Ke);const Qt=x.add(()=>a.close());aa(a,()=>{O=!1,Wt.dispose(),Zt(),Gt?.destroy?.(),Yt?.destroy?.(),s.removeEventListener("click",Se),s.removeEventListener("keydown",Ke),Qt()}),a.open(),I.scan(s)}async function zt(e){const t=A.peek().find(a=>a.id===e);if(t&&await ve(`Remove the import of <strong>${N(t.siteTitle||t.source)}</strong> from this list? Everything it imported stays on the site.`,{title:"Remove from the history",confirmText:"Remove"}))try{if(await q(`${$}/history/${e}`,{method:"DELETE"}),!i())return;A.value=A.peek().filter(a=>a.id!==e),R(Y)}catch(a){E.toast(`Not removed: ${a.message||a}`,{type:"error"})}}n.querySelector(".wpx-staged").innerHTML=ba,n.querySelector(".wpx-items").innerHTML=nt,n.querySelector(".wpx-redirects").innerHTML=rt,n.querySelector(".wpx-history").innerHTML=ga,n.querySelector(".wpx-tiles").innerHTML=it,n.querySelector(".wpx-note-list").innerHTML=lt,n.querySelector(".wpx-kinds").innerHTML=qe,n.querySelector(".wpx-filters").innerHTML=qe,n.querySelector(".wpx-facts").innerHTML=xa,n.querySelector(".wpx-product-notes").innerHTML=ya;const jt={mode:dt,job:b,jobTitle:Dt,jobText:Ot,jobPct:Ae,staged:d,stagedRows:mt,historyRows:ft,plan:g,planLoading:Q,planError:be,refreshing:we,opt:h,blogAvailable:C,blogNote:Pt,dirty:Re,canRun:Pe,siteTitle:Et,siteMeta:$t,tiles:xt,notes:kt,kinds:vt,filters:wt,rows:bt,moreText:gt,emptyText:yt,redirectRows:Mt,redirectCount:Tt,query:ee,uploadText:te,uploadError:j,dropping:oe,wxrLimit:Ut,zipInfo:ne,zipText:At,zipButton:It,zipUploadText:ae,shopAvailable:ut,hasProducts:Rt,productNote:St,productNoteCls:Lt,productFacts:qt,productNotes:Ct,optComments:B("comments"),optMenus:B("menus"),optRedirects:B("redirects"),optDrafts:B("drafts"),optProducts:B("products")},Bt=M.applyBindings(jt,n,{methods:{back:()=>Z(),discard:()=>De(),run:()=>_t(),resetChoices:()=>{h.value=Le(C.peek())},postsBlog:()=>D({posts:"blog"}),postsPages:()=>D({posts:"pages"}),postsSkip:()=>D({posts:"skip"}),mediaDownload:()=>D({media:"download"}),mediaZip:()=>D({media:"zip"}),mediaSkip:()=>D({media:"skip"}),removeZip:()=>Ht(),pickSeg:e=>{e.seg==="kind"?P.value=e.id:z.value=e.id},showProducts:()=>{P.value="product",z.value="all",ee.value="",n.querySelector(".wpx-items")?.closest(".wpx-card")?.scrollIntoView({behavior:"smooth",block:"start"})}}});x.add(()=>Bt.dispose()),x.add(We(n,{position:"bottom"}));const J=n.querySelector(".wpx-file"),Ue=()=>{const e=J.files?.[0];J.value="",Oe(e)};J.addEventListener("change",Ue);const U=n.querySelector(".wpx-drop"),Ne=e=>{e.preventDefault(),oe.value=!0},He=()=>{oe.value=!1},_e=e=>{e.preventDefault(),oe.value=!1,Oe(e.dataTransfer?.files?.[0])};U.addEventListener("dragover",Ne),U.addEventListener("dragleave",He),U.addEventListener("drop",_e);const de=n.querySelector(".wpx-zip-file"),ze=()=>{const e=de.files?.[0];de.value="",Nt(e)};de.addEventListener("change",ze),x.add(()=>{J.removeEventListener("change",Ue),U.removeEventListener("dragover",Ne),U.removeEventListener("dragleave",He),U.removeEventListener("drop",_e),de.removeEventListener("change",ze)}),he(n.querySelector(".wpx-staged"),".wpx-row",e=>[{header:d.peek().find(t=>t.id===e.dataset.id)?.siteTitle||"Upload"},{label:"Preview the import",icon:"eye",action:()=>ce(e.dataset.id)},{label:"Discard the upload",icon:"trash-2",action:()=>De(e.dataset.id)}],e=>ce(e.dataset.id));const Ft=(e,t)=>{h.value={...h.peek(),choices:na(h.peek().choices,e,t)}};he(n.querySelector(".wpx-items"),".wpx-row",e=>{const t=K.peek().find(s=>s.key===e.dataset.key);if(!t)return[];const a=[{header:t.title}];for(const s of ra(t,t.choice))a.push({label:s.label,icon:s.icon,action:()=>Ft(t.key,s.id)});return t.oldUrl&&/^https?:\/\//i.test(t.oldUrl)&&a.push({label:"Open the old address",icon:"link",action:()=>window.open(t.oldUrl,"_blank","noopener,noreferrer")}),t.target?.startsWith("/")&&(t.action==="update"||t.action==="keep")&&a.push({label:"Open it on this site",icon:"external-link",action:()=>window.open(t.target,"_blank","noopener")}),a.length===1&&a.push({label:"Nothing to change here",icon:"info",disabled:!0,action:()=>{}}),a},e=>X(e.querySelector(".wpx-kebab")||e)),he(n.querySelector(".wpx-redirects"),".wpx-row",e=>[{header:e.dataset.from},{label:"Copy the old address",icon:"copy",action:()=>pt(e.dataset.from)}],null),he(n.querySelector(".wpx-history"),".wpx-row",e=>[{header:A.peek().find(t=>t.id===e.dataset.id)?.siteTitle||"Import"},{label:"Open the report",icon:"file-text",action:()=>pe(e.dataset.id)},{label:"Remove from the history",icon:"trash-2",action:()=>zt(e.dataset.id)}],e=>pe(e.dataset.id)),ta(l,{id:"wpx-upload",icon:"upload",title:"Upload an export",onClick:()=>{u.peek()&&Z(),setTimeout(()=>J.click(),0)}}),I.scan(n);const Ee=Ge(p(),d.peek().map(e=>e.id),w);Ee.pruned&&y&&L({owner:w,items:Ee.items});const je=Object.entries(Ee.items).sort((e,t)=>String(t[1].at).localeCompare(String(e[1].at)))[0];je&&!b.peek()&&await ce(je[0])}};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "domma-cms",
3
- "version": "1.8.1",
3
+ "version": "1.8.3",
4
4
  "description": "File-based CMS powered by Domma and Fastify. Run npx domma-cms my-site to create a new project.",
5
5
  "type": "module",
6
6
  "main": "server/server.js",