domma-cms 0.7.1 → 0.7.5

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.
@@ -1 +1 @@
1
- export function getSidebarConfig(o=[],t={},l=[]){const e=n=>o.includes(n)||["read","create","update","delete"].some(r=>o.includes(`${n}.${r}`)),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=l.filter(n=>n.permissions?.length?n.permissions.some(r=>o.includes(r)):!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),(e("navigation")||e("layouts")||e("settings"))&&i.push({divider:!0},{heading:"Pro"},{id:"pro-docs",text:"Documentation",icon:"zap",url:"#/pro/docs",section:"#/pro/docs"}),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}
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 &amp; 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(n){Domma.icons.scan(),Domma.syntax.scan()}};
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()}};
@@ -72,6 +72,11 @@
72
72
  "icon": "mouse-pointer"
73
73
  }
74
74
  ]
75
+ },
76
+ {
77
+ "text": "Scratch",
78
+ "url": "/scratch",
79
+ "icon": "home"
75
80
  }
76
81
  ],
77
82
  "variant": "dark",
@@ -45,5 +45,13 @@
45
45
  "docs": {
46
46
  "enabled": false,
47
47
  "settings": {}
48
+ },
49
+ "garage": {
50
+ "enabled": true,
51
+ "settings": {}
52
+ },
53
+ "data-transfer": {
54
+ "enabled": true,
55
+ "settings": {}
48
56
  }
49
57
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "domma-cms",
3
- "version": "0.7.1",
3
+ "version": "0.7.5",
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",
@@ -1,8 +1,8 @@
1
1
  {
2
- "/": 161,
2
+ "/": 162,
3
3
  "/about": 88,
4
- "/blog": 36,
5
- "/contact": 30,
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": 23,
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": 70,
19
+ "/scratch": 82,
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 &rarr; 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 &rarr; 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 &rarr; 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>