domma-cms 0.7.1 → 0.7.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/admin/js/app.js +4 -4
- package/admin/js/config/sidebar-config.js +1 -1
- package/admin/js/templates/documentation.html +121 -0
- package/admin/js/views/documentation.js +1 -1
- package/config/navigation.json +5 -0
- package/config/plugins.json +8 -9
- package/package.json +1 -1
- package/plugins/analytics/stats.json +5 -5
- package/plugins/data-transfer/admin/templates/data-transfer.html +172 -0
- package/plugins/data-transfer/admin/views/data-transfer.js +558 -0
- package/plugins/data-transfer/config.js +9 -0
- package/plugins/data-transfer/plugin.js +424 -0
- package/plugins/data-transfer/plugin.json +33 -0
- package/plugins/garage/admin/templates/garage.html +81 -0
- package/plugins/garage/admin/views/garage.js +561 -0
- package/plugins/garage/config.js +18 -0
- package/plugins/garage/data/vehicles.json +70 -0
- package/plugins/garage/plugin.js +438 -0
- package/plugins/garage/plugin.json +33 -0
- package/server/routes/api/auth.js +17 -3
- package/server/routes/api/users.js +3 -0
- package/server/server.js +11 -3
- package/server/services/content.js +6 -2
- package/server/services/markdown.js +7 -7
- package/server/services/plugins.js +9 -3
- package/plugins/domma-effects/admin/templates/domma-effects.html +0 -577
- package/plugins/domma-effects/admin/views/domma-effects.js +0 -56
- package/plugins/domma-effects/config.js +0 -9
- package/plugins/domma-effects/plugin.js +0 -147
- package/plugins/domma-effects/plugin.json +0 -36
- package/plugins/domma-effects/public/celebrations/core/canvas.js +0 -9
- package/plugins/domma-effects/public/celebrations/core/particles.js +0 -1
- package/plugins/domma-effects/public/celebrations/core/physics.js +0 -1
- package/plugins/domma-effects/public/celebrations/index.js +0 -1
- package/plugins/domma-effects/public/celebrations/themes/christmas.js +0 -1
- package/plugins/domma-effects/public/celebrations/themes/guy-fawkes.js +0 -1
- package/plugins/domma-effects/public/celebrations/themes/halloween.js +0 -1
- package/plugins/domma-effects/public/celebrations/themes/st-andrews.js +0 -1
- package/plugins/domma-effects/public/celebrations/themes/st-davids.js +0 -1
- package/plugins/domma-effects/public/celebrations/themes/st-georges.js +0 -1
- package/plugins/domma-effects/public/celebrations/themes/st-patricks.js +0 -1
- package/plugins/domma-effects/public/celebrations/themes/valentines.js +0 -1
- package/plugins/domma-effects/public/inject-body.html +0 -287
package/admin/js/app.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{getSidebarConfig as J}from"./config/sidebar-config.js";import{views as
|
|
2
|
-
<span id="topbar-user-name" class="topbar-user-name">${
|
|
3
|
-
<span class="topbar-role-badge topbar-role-badge--${
|
|
1
|
+
import{getSidebarConfig as J}from"./config/sidebar-config.js";import{views as H}from"./views/index.js";import{api as o,getUser as l,isAuthenticated as r,logout as q}from"./api.js";$(()=>{(async()=>{try{const t=r()?await o.settings.get():null;Domma.theme.init({theme:t?.adminTheme||"charcoal-dark",persist:!0})}catch{Domma.theme.init({theme:"charcoal-dark",persist:!0})}})();const P=["jb-company","jb-agent","jb-candidate"],x=["/job-board","/my-profile"];function d(t){return t&&P.includes(t.role)}function m(t){return x.some(i=>t===i||t.startsWith(i+"/"))}R.use(async(t,i,a)=>{if(t.path==="/login"||t.path==="/reset-password")return a();if(!r()){R.navigate("/login");return}if(d(l())&&!m(t.path)){R.navigate("/job-board");return}a()});let c=null;async function j(){if(!r())return{};try{const[t,i,a,s,e,n,_,B,T,V,I,O,U]=await Promise.all([o.pages.list().catch(()=>[]),o.media.list().catch(()=>[]),o.users.list().catch(()=>[]),o.plugins.list().catch(()=>[]),o.collections.list().catch(()=>[]),o.forms.list().catch(()=>[]),o.themes.list().catch(()=>[]),o.views.list().catch(()=>[]),o.actions.list().catch(()=>[]),o.blocks.list().catch(()=>[]),o.navigation.get().catch(()=>({})),o.layouts.get().catch(()=>({})),o.get("/collections/roles/entries?limit=100").catch(()=>({entries:[]}))]),D=I.items||[],K=D.filter(h=>!h.hidden).length,y=D.length,F=s.filter(h=>h.enabled).length,k=s.length;return{pages:t.length,media:i.length,users:a.length,plugins:k>0?`${F}/${k}`:null,collections:e.length,forms:n.length,themes:_.length,views:B.length,actions:T.length,blocks:V.length,navigation:y>0?`${K}/${y}`:null,layouts:Object.keys(O).length,roles:(U.entries||[]).length}}catch{return{}}}async function g(){try{return(await o.get("/auth/permissions")).permissions||[]}catch{return[]}}async function A(){try{return await o.get("/settings/db-status")}catch{return{configured:!1}}}async function u(t){c&&$("#admin-sidebar").empty();const[i,a]=await Promise.all([j(),A()]),s=w.map(e=>{if(!e.countKey)return e;const n=i[e.countKey];return{...e,badge:n!=null&&n>0?String(n):null}});if(c=Domma.elements.sidebar("#admin-sidebar",{header:{title:"CMS Admin",icon:"layout"},items:J(t,i,s),collapsible:!0,collapseAt:992,push:!0,contentSelector:".dashboard-main",top:"60px"}),L(),N(),a?.configured){const e=$("#admin-sidebar").find(".sidebar-header-title").first();e.length&&!e.find(".db-badge").length&&e.append('<span class="db-badge" title="MongoDB connected" style="display:inline-flex;align-items:center;background:#16a34a;color:#fff;font-size:10px;font-weight:700;padding:2px 6px;border-radius:9999px;letter-spacing:.5px;margin-left:6px;vertical-align:middle;line-height:1;">DB</span>')}}function L(){$("#admin-sidebar .sidebar-link").each(function(){const t=$(this).find(".sidebar-text").text().trim();t&&$(this).attr("data-tooltip",t)}),E.tooltip("#admin-sidebar [data-tooltip]",{placement:"right"})}function N(){const t="sidebar_collapsed_sections",i=new Set(S.get(t)||[]);$("#admin-sidebar .sidebar-heading").each(function(){const a=$(this);a.addClass("sidebar-heading--collapsible"),a.append('<span class="sidebar-heading-toggle"><span data-icon="chevron-down"></span></span>');const s=a.text().trim();if(i.has(s)){a.addClass("is-collapsed");let e=a.next();for(;e.length&&!e.hasClass("sidebar-heading")&&!e.hasClass("sidebar-divider");)e.hide(),e=e.next()}a.on("click",function(){const e=!a.hasClass("is-collapsed");a.toggleClass("is-collapsed",e);let n=a.next();for(;n.length&&!n.hasClass("sidebar-heading")&&!n.hasClass("sidebar-divider");)n.toggle(!e),n=n.next();e?i.add(s):i.delete(s),S.set(t,[...i])})}),Domma.icons.scan("#admin-sidebar")}M.subscribe("router:afterChange",({to:t})=>{c&&t.path!=="/login"&&t.path!=="/reset-password"&&c.setActive("#"+t.path)});const W=[{path:"/",view:"dashboard",title:"Dashboard - 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:"/navigation",view:"navigation",title:"Navigation - Domma CMS"},{path:"/layouts",view:"layouts",title:"Layouts - Domma CMS"},{path:"/settings",view:"settings",title:"Settings - 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:"/documentation",view:"documentation",title:"Usage - Domma CMS"},{path:"/tutorials",view:"tutorials",title:"Tutorials - 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:"/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:"/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(!(t.path==="/login"||t.path==="/reset-password")){if(d(l())&&!m(t.path)){R.navigate("/job-board");return}if($("#admin-sidebar").show(),$("#admin-topbar").show(),i?.path==="/login"||i?.path==="/reset-password"){$("#topbar-user-name").remove(),await f();const a=await g();u(a)}v()}}),M.subscribe("router:afterChange",()=>{setTimeout(()=>{$(".btn-primary, .btn-danger").length&&Domma.effects.reveal(".btn-primary, .btn-danger",{animation:"fade",stagger:40,duration:300})},50)}),$("#view-container").on("click",".card-collapsible .card-header",function(t){$(t.target).closest("button, a").length||$(this).closest(".card").toggleClass("card-collapsed")}),document.addEventListener("keydown",t=>{if(!(t.ctrlKey||t.metaKey)||t.key!=="s"||window.location.hash==="#/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 b={...H},p=[...W];let w=[];async function f(){if(r())try{const t=await o.plugins.adminConfig();w=t.sidebar||[],t.routes?.length&&p.push(...t.routes);for(const[i,a]of Object.entries(t.views||{}))try{const s=await import(`/plugins/${a.entry}`);b[i]=s[a.exportName]}catch{}}catch{}}function v(){const t=l();if(!t||$("#topbar-user-name").length)return;const a={admin:"Admin",manager:"Manager",editor:"Editor",subscriber:"Subscriber","jb-company":"Company","jb-agent":"Agent","jb-candidate":"Candidate"}[t.role]||t.role;$("#topbar-user").html(`
|
|
2
|
+
<span id="topbar-user-name" class="topbar-user-name">${C(t.name)}</span>
|
|
3
|
+
<span class="topbar-role-badge topbar-role-badge--${C(t.role)}">${a}</span>
|
|
4
4
|
`),$("#topbar-actions").html(`
|
|
5
5
|
<a href="#/my-profile" class="topbar-action-link" data-tooltip="My Profile" data-tooltip-placement="bottom">
|
|
6
6
|
<span data-icon="user"></span>
|
|
@@ -14,4 +14,4 @@ import{getSidebarConfig as J}from"./config/sidebar-config.js";import{views as K}
|
|
|
14
14
|
<span data-icon="log-out"></span>
|
|
15
15
|
<span>Sign out</span>
|
|
16
16
|
</a>
|
|
17
|
-
`),$("#topbar-logout-btn").on("click",
|
|
17
|
+
`),$("#topbar-logout-btn").on("click",s=>{s.preventDefault(),q()}),Domma.icons.scan("#admin-topbar"),E.tooltip("#topbar-actions [data-tooltip]",{placement:"bottom"})}function C(t){return String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}(async()=>{if(!r()&&!window.location.hash.startsWith("#/reset-password"))window.location.hash="#/login";else{const s=(window.location.hash||"#/").slice(1)||"/";if(d(l())&&!m(s)&&(window.location.hash="#/job-board"),await f(),l()){const n=await g();await u(n),v()}}R.init({container:"#view-container",routes:p,views:b,default:"/",transitions:{enter:"fadeIn",leave:"fadeOut",duration:150}});const t=R._extractParams.bind(R);R._extractParams=function(s,e){if(s.endsWith("/*")){const n=s.slice(0,-2);return e.startsWith(n+"/")?{}:null}return t(s,e)};const i=(window.location.hash||"#/").slice(1)||"/";p.filter(s=>s.path.endsWith("/*")).some(s=>i.startsWith(s.path.slice(0,-2)+"/"))&&R._handleRouteChange()})()});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export function getSidebarConfig(o=[],t={},
|
|
1
|
+
export function getSidebarConfig(o=[],t={},r=[]){const e=n=>o.includes(n)||["read","create","update","delete"].some(l=>o.includes(`${n}.${l}`)),s=n=>n==null?null:typeof n=="string"?n.length>0?n:null:n>0?String(n):null,i=[],u=o.length>0&&o.every(n=>n.startsWith("jb-"));u||i.push({heading:"Overview"},{id:"dashboard",text:"Dashboard",icon:"home",url:"#/",section:"#/"},{divider:!0}),(e("navigation")||e("layouts"))&&i.push({heading:"Structure"},...e("navigation")?[{id:"navigation",text:"Navigation",icon:"menu",url:"#/navigation",section:"#/navigation",badge:s(t.navigation)}]:[],...e("layouts")?[{id:"layouts",text:"Layouts",icon:"layout",url:"#/layouts",section:"#/layouts",badge:s(t.layouts)}]:[],{divider:!0}),(e("pages")||e("media"))&&(i.push({heading:"Content"}),e("pages")&&i.push({id:"pages",text:"Pages",icon:"file-text",url:"#/pages",section:"#/pages",badge:s(t.pages)}),e("media")&&i.push({id:"media",text:"Media",icon:"image",url:"#/media",section:"#/media",badge:s(t.media)})),(e("collections")||e("views")||e("actions"))&&(i.push({divider:!0},{heading:"Data"}),e("collections")&&(i.push({id:"collections",text:"Collections",icon:"database",url:"#/collections",section:"#/collections",badge:s(t.collections)}),i.push({id:"forms",text:"Forms",icon:"layout",url:"#/forms",section:"#/forms",badge:s(t.forms)})),e("views")&&i.push({id:"views",text:"Views",icon:"eye",url:"#/views",section:"#/views",badge:s(t.views)}),e("actions")&&i.push({id:"actions",text:"Actions",icon:"zap",url:"#/actions",section:"#/actions",badge:s(t.actions)}),e("pages")&&i.push({id:"blocks",text:"Blocks",icon:"box",url:"#/blocks",section:"#/blocks",badge:s(t.blocks)})),(e("plugins")||e("users")||e("settings"))&&(i.push({divider:!0},{heading:"Configuration"}),e("plugins")&&i.push({id:"roles",text:"Roles",icon:"shield",url:"#/roles",section:"#/roles",badge:s(t.roles)}),e("users")&&i.push({id:"users",text:"Users",icon:"users",url:"#/users",section:"#/users",badge:s(t.users)}),e("settings")&&i.push({id:"settings",text:"Site Settings",icon:"settings",url:"#/settings",section:"#/settings"}));const a=r.filter(n=>n.permissions?.length?n.permissions.some(l=>o.includes(l)):!0);return e("plugins")?i.push({divider:!0},{heading:"Plugins"},{id:"plugins",text:"Plugins",icon:"package",url:"#/plugins",section:"#/plugins",badge:s(t.plugins)},...a):a.length&&i.push({divider:!0},...a),i.push({divider:!0},{heading:"Account"},{id:"my-profile",text:"My Profile",icon:"user",url:"#/my-profile",section:"#/my-profile"}),u||i.push({divider:!0},{heading:"View Site"},{id:"view-site",text:"View Site",icon:"external-link",url:"/",section:"/"}),(e("pages")||e("collections")||e("plugins")||e("settings"))&&i.push({divider:!0},{heading:"Documentation"},{id:"documentation",text:"Usage",icon:"book",url:"#/documentation",section:"#/documentation",badge:s(t.documents)},{id:"tutorials",text:"Tutorials",icon:"document",url:"#/tutorials",section:"#/documentation",badge:s(t.tutorials)},{id:"api-reference",text:"API Reference",icon:"code",url:"#/api-reference",section:"#/documentation"}),i}
|
|
@@ -627,5 +627,126 @@ Step 3: email to={{entry.data.email}}
|
|
|
627
627
|
</div>
|
|
628
628
|
</div>
|
|
629
629
|
|
|
630
|
+
<!-- CTA Shortcode -->
|
|
631
|
+
<div class="card card-collapsible mb-4">
|
|
632
|
+
<div class="card-header" role="button" tabindex="0">
|
|
633
|
+
<div class="card-header-content"><h2><span data-icon="mouse-pointer"></span> CTA Shortcode <span
|
|
634
|
+
class="badge badge-warning" style="font-size:.7rem;">Pro</span></h2></div>
|
|
635
|
+
<span class="card-collapse-icon" data-icon="chevron-down"></span>
|
|
636
|
+
</div>
|
|
637
|
+
<div class="card-body docs-body">
|
|
638
|
+
<p>The <code>[cta]</code> shortcode places an action-trigger button in any public page. Clicking it calls
|
|
639
|
+
<code>POST /api/actions/:slug/public</code> with the entry ID, using the logged-in user's JWT.
|
|
640
|
+
If the user is not logged in, a warning toast is shown instead.</p>
|
|
641
|
+
|
|
642
|
+
<h3>Syntax & Attributes</h3>
|
|
643
|
+
<p><strong>Wrapping form:</strong></p>
|
|
644
|
+
<pre class="code-block"><code>[cta action="slug" entry="entry-id" icon="check" confirm="Are you sure?"]Button label[/cta]</code></pre>
|
|
645
|
+
<p><strong>Self-closing form:</strong></p>
|
|
646
|
+
<pre class="code-block"><code>[cta action="slug" entry="entry-id" label="Button label" /]</code></pre>
|
|
647
|
+
<table class="table table-sm" style="margin-top:1rem;">
|
|
648
|
+
<thead>
|
|
649
|
+
<tr>
|
|
650
|
+
<th>Attribute</th>
|
|
651
|
+
<th>Required</th>
|
|
652
|
+
<th>Default</th>
|
|
653
|
+
<th>Description</th>
|
|
654
|
+
</tr>
|
|
655
|
+
</thead>
|
|
656
|
+
<tbody>
|
|
657
|
+
<tr>
|
|
658
|
+
<td><code>action</code></td>
|
|
659
|
+
<td>Yes</td>
|
|
660
|
+
<td>—</td>
|
|
661
|
+
<td>Action slug</td>
|
|
662
|
+
</tr>
|
|
663
|
+
<tr>
|
|
664
|
+
<td><code>entry</code></td>
|
|
665
|
+
<td>Yes</td>
|
|
666
|
+
<td>—</td>
|
|
667
|
+
<td>Entry UUID to act on</td>
|
|
668
|
+
</tr>
|
|
669
|
+
<tr>
|
|
670
|
+
<td><code>label</code></td>
|
|
671
|
+
<td>No</td>
|
|
672
|
+
<td><code>"Run"</code></td>
|
|
673
|
+
<td>Button text (self-closing only)</td>
|
|
674
|
+
</tr>
|
|
675
|
+
<tr>
|
|
676
|
+
<td><code>style</code></td>
|
|
677
|
+
<td>No</td>
|
|
678
|
+
<td><code>"primary"</code></td>
|
|
679
|
+
<td>primary · secondary · ghost · danger</td>
|
|
680
|
+
</tr>
|
|
681
|
+
<tr>
|
|
682
|
+
<td><code>icon</code></td>
|
|
683
|
+
<td>No</td>
|
|
684
|
+
<td>—</td>
|
|
685
|
+
<td>Domma icon name</td>
|
|
686
|
+
</tr>
|
|
687
|
+
<tr>
|
|
688
|
+
<td><code>size</code></td>
|
|
689
|
+
<td>No</td>
|
|
690
|
+
<td>—</td>
|
|
691
|
+
<td>sm · md · lg</td>
|
|
692
|
+
</tr>
|
|
693
|
+
<tr>
|
|
694
|
+
<td><code>confirm</code></td>
|
|
695
|
+
<td>No</td>
|
|
696
|
+
<td>—</td>
|
|
697
|
+
<td>Confirmation prompt before executing</td>
|
|
698
|
+
</tr>
|
|
699
|
+
</tbody>
|
|
700
|
+
</table>
|
|
701
|
+
|
|
702
|
+
<h3>Collection Integration</h3>
|
|
703
|
+
<p>Add per-entry buttons to any <code>[collection]</code> shortcode:</p>
|
|
704
|
+
<pre class="code-block"><code>[collection slug="applications" display="cards" title-field="name"
|
|
705
|
+
cta="approve-application"
|
|
706
|
+
cta-label="Approve"
|
|
707
|
+
cta-icon="check"
|
|
708
|
+
cta-style="primary"
|
|
709
|
+
cta-confirm="Approve this application?" /]</code></pre>
|
|
710
|
+
<table class="table table-sm" style="margin-top:1rem;">
|
|
711
|
+
<thead>
|
|
712
|
+
<tr>
|
|
713
|
+
<th>Attribute</th>
|
|
714
|
+
<th>Default</th>
|
|
715
|
+
<th>Description</th>
|
|
716
|
+
</tr>
|
|
717
|
+
</thead>
|
|
718
|
+
<tbody>
|
|
719
|
+
<tr>
|
|
720
|
+
<td><code>cta</code></td>
|
|
721
|
+
<td>—</td>
|
|
722
|
+
<td>Action slug — enables per-entry buttons</td>
|
|
723
|
+
</tr>
|
|
724
|
+
<tr>
|
|
725
|
+
<td><code>cta-label</code></td>
|
|
726
|
+
<td><code>"Run"</code></td>
|
|
727
|
+
<td>Button label</td>
|
|
728
|
+
</tr>
|
|
729
|
+
<tr>
|
|
730
|
+
<td><code>cta-icon</code></td>
|
|
731
|
+
<td>—</td>
|
|
732
|
+
<td>Domma icon name</td>
|
|
733
|
+
</tr>
|
|
734
|
+
<tr>
|
|
735
|
+
<td><code>cta-style</code></td>
|
|
736
|
+
<td><code>"primary"</code></td>
|
|
737
|
+
<td>Button variant</td>
|
|
738
|
+
</tr>
|
|
739
|
+
<tr>
|
|
740
|
+
<td><code>cta-confirm</code></td>
|
|
741
|
+
<td>—</td>
|
|
742
|
+
<td>Confirmation prompt</td>
|
|
743
|
+
</tr>
|
|
744
|
+
</tbody>
|
|
745
|
+
</table>
|
|
746
|
+
<p>All three display modes support CTA buttons: <strong>cards</strong> (card footer),
|
|
747
|
+
<strong>list</strong> (inline), <strong>table</strong> (dedicated column).</p>
|
|
748
|
+
</div>
|
|
749
|
+
</div>
|
|
750
|
+
|
|
630
751
|
</div>
|
|
631
752
|
</div>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const documentationView={templateUrl:"/admin/js/templates/documentation.html",async onMount(
|
|
1
|
+
export const documentationView={templateUrl:"/admin/js/templates/documentation.html",async onMount(t){Domma.elements.collapsible(t.get(0)),Domma.icons.scan(),Domma.syntax.scan()}};
|
package/config/navigation.json
CHANGED
package/config/plugins.json
CHANGED
|
@@ -17,15 +17,6 @@
|
|
|
17
17
|
"debounceMs": 300
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
|
-
"domma-effects": {
|
|
21
|
-
"enabled": true,
|
|
22
|
-
"settings": {
|
|
23
|
-
"respectMotion": false,
|
|
24
|
-
"defaultDuration": 600,
|
|
25
|
-
"defaultAnimation": "fade",
|
|
26
|
-
"defaultThreshold": 0.1
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
20
|
"job-board": {
|
|
30
21
|
"enabled": false,
|
|
31
22
|
"settings": {}
|
|
@@ -45,5 +36,13 @@
|
|
|
45
36
|
"docs": {
|
|
46
37
|
"enabled": false,
|
|
47
38
|
"settings": {}
|
|
39
|
+
},
|
|
40
|
+
"garage": {
|
|
41
|
+
"enabled": true,
|
|
42
|
+
"settings": {}
|
|
43
|
+
},
|
|
44
|
+
"data-transfer": {
|
|
45
|
+
"enabled": true,
|
|
46
|
+
"settings": {}
|
|
48
47
|
}
|
|
49
48
|
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
-
"/":
|
|
2
|
+
"/": 162,
|
|
3
3
|
"/about": 88,
|
|
4
|
-
"/blog":
|
|
5
|
-
"/contact":
|
|
4
|
+
"/blog": 42,
|
|
5
|
+
"/contact": 31,
|
|
6
6
|
"/resources/typography": 4,
|
|
7
7
|
"/resources": 13,
|
|
8
8
|
"/resources/shortcodes": 14,
|
|
@@ -11,12 +11,12 @@
|
|
|
11
11
|
"/resources/grid": 6,
|
|
12
12
|
"/forms": 14,
|
|
13
13
|
"/resources/effects": 6,
|
|
14
|
-
"/blog/hello-world":
|
|
14
|
+
"/blog/hello-world": 28,
|
|
15
15
|
"/feedback": 42,
|
|
16
16
|
"/resources/dependencies": 2,
|
|
17
17
|
"/resources/components": 6,
|
|
18
18
|
"/gdpr": 3,
|
|
19
|
-
"/scratch":
|
|
19
|
+
"/scratch": 84,
|
|
20
20
|
"/getting-started": 3,
|
|
21
21
|
"/resources/pro": 1,
|
|
22
22
|
"/todo": 23,
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
<div class="data-transfer-plugin">
|
|
2
|
+
|
|
3
|
+
<div class="mb-4" style="display:flex;align-items:center;gap:0.75rem;">
|
|
4
|
+
<span data-icon="hard-drive" style="width:28px;height:28px;opacity:0.8;"></span>
|
|
5
|
+
<div>
|
|
6
|
+
<h1 style="font-size:1.25rem;font-weight:600;margin:0;">Data Transfer</h1>
|
|
7
|
+
<p style="font-size:0.875rem;color:var(--dm-text-muted);margin:0;">Bulk transfer, backup, restore, and clone
|
|
8
|
+
collections.</p>
|
|
9
|
+
</div>
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
<div id="dt-tabs" class="tabs">
|
|
13
|
+
<div class="tab-list" role="tablist">
|
|
14
|
+
<button class="tab-item active" data-tab="transfer">Transfer</button>
|
|
15
|
+
<button class="tab-item" data-tab="backups">Backups</button>
|
|
16
|
+
<button class="tab-item" data-tab="clone">Clone</button>
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
<div class="tab-content">
|
|
20
|
+
|
|
21
|
+
<!-- ===== Transfer ===== -->
|
|
22
|
+
<div class="tab-panel active" data-panel="transfer">
|
|
23
|
+
<div class="card mt-4">
|
|
24
|
+
<div class="card-header">
|
|
25
|
+
<strong>Move Collections Between Storage Adapters</strong>
|
|
26
|
+
</div>
|
|
27
|
+
<div class="card-body">
|
|
28
|
+
|
|
29
|
+
<div id="dt-mongo-warning" class="card mb-3"
|
|
30
|
+
style="display:none;border-left:3px solid var(--dm-warning);">
|
|
31
|
+
<div class="card-body"
|
|
32
|
+
style="display:flex;align-items:center;gap:0.5rem;padding:0.65rem 0.875rem;">
|
|
33
|
+
<span data-icon="alert-triangle" style="width:16px;height:16px;flex-shrink:0;"></span>
|
|
34
|
+
<span style="font-size:0.875rem;">MongoDB is not connected. File → MongoDB transfers are unavailable.</span>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<div class="form-group mb-4">
|
|
39
|
+
<label class="form-label">Direction</label>
|
|
40
|
+
<div style="display:flex;gap:1.5rem;margin-top:0.25rem;">
|
|
41
|
+
<label style="display:flex;align-items:center;gap:0.5rem;cursor:pointer;">
|
|
42
|
+
<input type="radio" name="dt-direction" value="file-to-mongo" id="dt-dir-ftm"
|
|
43
|
+
checked class="form-check-input">
|
|
44
|
+
File → MongoDB
|
|
45
|
+
</label>
|
|
46
|
+
<label style="display:flex;align-items:center;gap:0.5rem;cursor:pointer;">
|
|
47
|
+
<input type="radio" name="dt-direction" value="mongo-to-file" id="dt-dir-mtf"
|
|
48
|
+
class="form-check-input">
|
|
49
|
+
MongoDB → File
|
|
50
|
+
</label>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
<div id="dt-collections-loading" style="font-size:0.875rem;color:var(--dm-text-muted);">Loading
|
|
55
|
+
collections…
|
|
56
|
+
</div>
|
|
57
|
+
|
|
58
|
+
<div id="dt-collections-wrap" style="display:none;">
|
|
59
|
+
<table class="table mb-3" id="dt-collections-table">
|
|
60
|
+
<thead>
|
|
61
|
+
<tr>
|
|
62
|
+
<th style="width:36px;">
|
|
63
|
+
<input type="checkbox" id="dt-select-all" class="form-check-input"
|
|
64
|
+
title="Select all">
|
|
65
|
+
</th>
|
|
66
|
+
<th>Collection</th>
|
|
67
|
+
<th>Slug</th>
|
|
68
|
+
<th>Adapter</th>
|
|
69
|
+
<th>Entries</th>
|
|
70
|
+
</tr>
|
|
71
|
+
</thead>
|
|
72
|
+
<tbody id="dt-collections-body"></tbody>
|
|
73
|
+
</table>
|
|
74
|
+
|
|
75
|
+
<button class="btn btn-primary" id="dt-transfer-btn">
|
|
76
|
+
<span data-icon="arrow-left-right" style="width:14px;height:14px;"></span>
|
|
77
|
+
Transfer Selected
|
|
78
|
+
</button>
|
|
79
|
+
</div>
|
|
80
|
+
|
|
81
|
+
<div id="dt-transfer-results" style="display:none;margin-top:1.5rem;">
|
|
82
|
+
<strong style="display:block;margin-bottom:0.5rem;">Results</strong>
|
|
83
|
+
<div id="dt-transfer-results-body"></div>
|
|
84
|
+
</div>
|
|
85
|
+
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
|
|
90
|
+
<!-- ===== Backups ===== -->
|
|
91
|
+
<div class="tab-panel" data-panel="backups">
|
|
92
|
+
<div class="card mt-4">
|
|
93
|
+
<div class="card-header" style="display:flex;align-items:center;justify-content:space-between;">
|
|
94
|
+
<strong>Backup Snapshots</strong>
|
|
95
|
+
<button class="btn btn-primary btn-sm" id="dt-create-backup-btn">
|
|
96
|
+
<span data-icon="download" style="width:14px;height:14px;"></span>
|
|
97
|
+
Create Backup
|
|
98
|
+
</button>
|
|
99
|
+
</div>
|
|
100
|
+
<div class="card-body">
|
|
101
|
+
<div id="dt-backups-loading" style="font-size:0.875rem;color:var(--dm-text-muted);">Loading
|
|
102
|
+
backups…
|
|
103
|
+
</div>
|
|
104
|
+
<div id="dt-backups-wrap" style="display:none;">
|
|
105
|
+
<table class="table" id="dt-backups-table">
|
|
106
|
+
<thead>
|
|
107
|
+
<tr>
|
|
108
|
+
<th>Timestamp</th>
|
|
109
|
+
<th>Collections</th>
|
|
110
|
+
<th>Total Entries</th>
|
|
111
|
+
<th style="width:180px;">Actions</th>
|
|
112
|
+
</tr>
|
|
113
|
+
</thead>
|
|
114
|
+
<tbody id="dt-backups-body"></tbody>
|
|
115
|
+
</table>
|
|
116
|
+
<p id="dt-backups-empty"
|
|
117
|
+
style="display:none;font-size:0.875rem;color:var(--dm-text-muted);">No backups yet.</p>
|
|
118
|
+
</div>
|
|
119
|
+
</div>
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
|
|
123
|
+
<!-- ===== Clone ===== -->
|
|
124
|
+
<div class="tab-panel" data-panel="clone">
|
|
125
|
+
<div class="card mt-4" style="max-width:520px;">
|
|
126
|
+
<div class="card-header">
|
|
127
|
+
<strong>Clone a Collection</strong>
|
|
128
|
+
</div>
|
|
129
|
+
<div class="card-body">
|
|
130
|
+
|
|
131
|
+
<div class="form-group mb-3">
|
|
132
|
+
<label class="form-label" for="dt-clone-source">Source Collection</label>
|
|
133
|
+
<select class="form-input" id="dt-clone-source">
|
|
134
|
+
<option value="">— select —</option>
|
|
135
|
+
</select>
|
|
136
|
+
</div>
|
|
137
|
+
|
|
138
|
+
<div class="form-group mb-3">
|
|
139
|
+
<label class="form-label" for="dt-clone-title">New Title</label>
|
|
140
|
+
<input type="text" class="form-input" id="dt-clone-title"
|
|
141
|
+
placeholder="e.g. My Collection Copy">
|
|
142
|
+
</div>
|
|
143
|
+
|
|
144
|
+
<div class="form-group mb-3">
|
|
145
|
+
<label class="form-label" for="dt-clone-slug">
|
|
146
|
+
New Slug
|
|
147
|
+
<span style="font-size:0.8rem;color:var(--dm-text-muted);">(auto-generated)</span>
|
|
148
|
+
</label>
|
|
149
|
+
<input type="text" class="form-input" id="dt-clone-slug"
|
|
150
|
+
placeholder="e.g. my-collection-copy">
|
|
151
|
+
</div>
|
|
152
|
+
|
|
153
|
+
<div class="form-group mb-4">
|
|
154
|
+
<label style="display:flex;align-items:center;gap:0.5rem;cursor:pointer;">
|
|
155
|
+
<input type="checkbox" class="form-check-input" id="dt-clone-entries">
|
|
156
|
+
Copy entries (with new IDs)
|
|
157
|
+
</label>
|
|
158
|
+
</div>
|
|
159
|
+
|
|
160
|
+
<button class="btn btn-primary" id="dt-clone-btn">
|
|
161
|
+
<span data-icon="copy" style="width:14px;height:14px;"></span>
|
|
162
|
+
Clone Collection
|
|
163
|
+
</button>
|
|
164
|
+
|
|
165
|
+
</div>
|
|
166
|
+
</div>
|
|
167
|
+
</div>
|
|
168
|
+
|
|
169
|
+
</div>
|
|
170
|
+
</div>
|
|
171
|
+
|
|
172
|
+
</div>
|