domma-cms 1.6.60 → 1.7.0
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/CHANGELOG.md +4344 -0
- package/README.md +1 -1
- package/admin/dist/domma/domma-tools.css +3 -3
- package/admin/dist/domma/domma-tools.min.js +3 -3
- package/admin/js/lib/effect-defs.js +1 -1
- package/admin/js/lib/effects-builder.js +2 -2
- package/admin/js/lib/page-editor-reference.js +5 -5
- package/admin/js/lib/shortcode-tags.js +1 -1
- package/admin/js/templates/docs/usage-shortcodes.html +39 -0
- package/docs/DommaFeatures.md +3005 -0
- package/docs/MultiTenant.md +176 -0
- package/docs/api-reference.md +1667 -0
- package/docs/cache.md +96 -0
- package/docs/configuration.md +1811 -0
- package/docs/editions-and-licences.md +190 -0
- package/docs/getting-started.md +201 -0
- package/docs/guides/form-triggers.md +260 -0
- package/docs/guides/mongodb-storage-adapter.md +282 -0
- package/docs/guides/multi-page-forms.md +121 -0
- package/docs/images/scribe-composer.png +0 -0
- package/docs/markdown-shortcodes.md +1738 -0
- package/docs/pentest-report-2026-04-03.md +181 -0
- package/docs/plans/2026-02-28-admin-topbar-login-forms.md +349 -0
- package/docs/plans/2026-02-28-domma-ui-polish.md +286 -0
- package/docs/plans/2026-02-28-reset-seed-fresh-commands.md +520 -0
- package/docs/plans/2026-03-02-cookie-consent-design.md +86 -0
- package/docs/plans/2026-03-02-cookie-consent-plugin.md +453 -0
- package/docs/plans/2026-03-02-tooltip-sweep-and-back-to-top-plugin-design.md +126 -0
- package/docs/plans/2026-03-02-tooltip-sweep-back-to-top.md +427 -0
- package/docs/plans/2026-03-05-cookie-consent-btt-core.md +115 -0
- package/docs/plans/2026-03-05-custom-css-migrate-to-core-design.md +35 -0
- package/docs/plans/2026-03-05-custom-css-migrate-to-core.md +352 -0
- package/docs/plans/2026-03-05-scribe-script-shortcode.md +373 -0
- package/docs/plans/2026-03-05-user-types-design.md +139 -0
- package/docs/plans/2026-03-05-user-types-implementation.md +1035 -0
- package/docs/plans/2026-03-09-page-editor-view-cta-inserts-design.md +78 -0
- package/docs/plans/2026-03-09-page-editor-view-cta-inserts.md +388 -0
- package/docs/plans/2026-03-09-pro-documentation-design.md +80 -0
- package/docs/plans/2026-03-09-pro-documentation.md +1017 -0
- package/docs/plans/2026-06-10-core-project-design.md +240 -0
- package/docs/plugin-development.md +827 -0
- package/docs/recruitment-recipe.md +501 -0
- package/docs/scaffolding.md +312 -0
- package/docs/screenshots/calculator-floating.png +0 -0
- package/docs/screenshots/calculator-standard.png +0 -0
- package/docs/screenshots/email-settings.png +0 -0
- package/docs/screenshots/messages-count.png +0 -0
- package/docs/structure/user-types.md +107 -0
- package/docs/superpowers/plans/2026-05-25-admin-sidebar-via-menus.md +1112 -0
- package/docs/superpowers/plans/2026-06-08-navbar-mobile-drawer-and-menu-enrichment.md +1161 -0
- package/docs/superpowers/plans/2026-06-25-domma-docs-project.md +695 -0
- package/docs/superpowers/plans/2026-06-26-surveys-HANDOFF.md +68 -0
- package/docs/superpowers/plans/2026-06-26-surveys-pro-plugin.md +1902 -0
- package/docs/superpowers/plans/2026-08-19-collection-context-sort-export.md +1577 -0
- package/docs/superpowers/plans/2026-10-09-content-api.md +1192 -0
- package/docs/superpowers/specs/2026-03-12-form-followup-actions-design.md +152 -0
- package/docs/superpowers/specs/2026-03-12-page-editor-form-insert-and-per-page-theme-design.md +115 -0
- package/docs/superpowers/specs/2026-03-17-nav-hidden-items-design.md +85 -0
- package/docs/superpowers/specs/2026-03-19-accordion-insert-design.md +175 -0
- package/docs/superpowers/specs/2026-03-25-static-block-shortcode-design.md +153 -0
- package/docs/superpowers/specs/2026-03-25-text-shortcode-design.md +168 -0
- package/docs/superpowers/specs/2026-04-05-card-builder-design.md +315 -0
- package/docs/superpowers/specs/2026-04-06-insert-builders-design.md +278 -0
- package/docs/superpowers/specs/2026-04-06-layouts-design.md +226 -0
- package/docs/superpowers/specs/2026-04-07-blog-plugin-design.md +300 -0
- package/docs/superpowers/specs/2026-04-07-calendar-plugin-design.md +538 -0
- package/docs/superpowers/specs/2026-04-17-components-area-design.md +368 -0
- package/docs/superpowers/specs/2026-05-02-effects-slideover-overhaul-design.md +193 -0
- package/docs/superpowers/specs/2026-05-06-dashboard-rebuild-design.md +257 -0
- package/docs/superpowers/specs/2026-05-24-menus-design.md +466 -0
- package/docs/superpowers/specs/2026-05-25-admin-sidebar-via-menus-design.md +358 -0
- package/docs/superpowers/specs/2026-05-25-projects-design.md +380 -0
- package/docs/superpowers/specs/2026-06-08-navbar-mobile-drawer-and-menu-enrichment-design.md +292 -0
- package/docs/superpowers/specs/2026-06-08-sidebar-tools-plugins-folders-design.md +59 -0
- package/docs/superpowers/specs/2026-06-25-domma-docs-project-design.md +192 -0
- package/docs/superpowers/specs/2026-06-26-domma-charts-upstream-proposal.md +44 -0
- package/docs/superpowers/specs/2026-06-26-manager-scheduler-upstream-proposal.md +46 -0
- package/docs/superpowers/specs/2026-06-26-surveys-pro-plugin-design.md +206 -0
- package/docs/superpowers/specs/2026-07-02-shortcode-context-menu-design.md +96 -0
- package/docs/superpowers/specs/2026-08-19-collection-context-sort-export-design.md +330 -0
- package/docs/superpowers/specs/2026-09-22-dcms-marketplace-design.md +1150 -0
- package/docs/superpowers/specs/2026-10-09-content-api-design.md +325 -0
- package/docs/superpowers/specs/plans/2026-03-12-form-followup-actions.md +624 -0
- package/docs/superpowers/specs/plans/2026-03-12-page-editor-form-insert-and-per-page-theme.md +125 -0
- package/docs/superpowers/specs/plans/2026-03-17-nav-hidden-items.md +578 -0
- package/docs/superpowers/specs/plans/2026-03-19-accordion-insert.md +635 -0
- package/docs/superpowers/specs/plans/2026-03-25-text-shortcode.md +545 -0
- package/docs/superpowers/specs/plans/2026-04-05-card-builder.md +1970 -0
- package/docs/superpowers/specs/plans/2026-04-06-insert-builders.md +1049 -0
- package/docs/superpowers/specs/plans/2026-04-06-layouts.md +1015 -0
- package/docs/superpowers/specs/plans/2026-04-07-calendar-plugin.md +1526 -0
- package/docs/superpowers/specs/plans/2026-04-08-plugin-monetisation-split.md +242 -0
- package/docs/superpowers/specs/plans/2026-04-17-components-area.md +2038 -0
- package/docs/superpowers/specs/plans/2026-05-02-effects-slideover-overhaul.md +2335 -0
- package/docs/superpowers/specs/plans/2026-05-06-dashboard-rebuild.md +1999 -0
- package/docs/superpowers/specs/plans/2026-05-17-cache-system.md +1436 -0
- package/docs/superpowers/specs/plans/2026-05-24-menus.md +3096 -0
- package/docs/superpowers/specs/plans/2026-05-25-projects.md +2869 -0
- package/docs/superpowers/specs/plans/2026-09-22-marketplace-step2-consolidation.md +505 -0
- package/docs/superpowers/specs/plans/2026-09-22-marketplace-step3-catalogue-and-key.md +154 -0
- package/docs/superpowers/specs/plans/2026-09-22-tools-promotion.md +260 -0
- package/docs/theming.md +320 -0
- package/package.json +2 -2
- package/public/js/celebrations/core/canvas.js +1 -1
- package/public/js/celebrations/index.js +1 -1
- package/public/js/celebrations/licenses/ABeeZee-Regular-OFL.txt +93 -0
- package/public/js/celebrations/licenses/Allura-Regular-OFL.txt +93 -0
- package/public/js/celebrations/message-attrs.mjs +1 -0
- package/public/js/celebrations/themes/anniversary.js +1 -0
- package/public/js/celebrations/themes/autumn.js +1 -0
- package/public/js/celebrations/themes/birthday.js +1 -0
- package/public/js/celebrations/themes/butterfly-flight.js +1 -0
- package/public/js/celebrations/themes/calendar.js +1 -0
- package/public/js/celebrations/themes/chinese-new-year-dates.js +1 -0
- package/public/js/celebrations/themes/chinese-new-year.js +1 -0
- package/public/js/celebrations/themes/christmas.js +1 -1
- package/public/js/celebrations/themes/easter.js +1 -0
- package/public/js/celebrations/themes/garden-drawing.js +1 -0
- package/public/js/celebrations/themes/garden.js +1 -0
- package/public/js/celebrations/themes/graduation.js +1 -0
- package/public/js/celebrations/themes/greeting.js +1 -0
- package/public/js/celebrations/themes/make-it-rain.js +1 -0
- package/public/js/celebrations/themes/money-rain.js +1 -0
- package/public/js/celebrations/themes/new-year.js +1 -0
- package/public/js/celebrations/themes/occasion-drawing.js +1 -0
- package/public/js/celebrations/themes/occasions.js +1 -0
- package/public/js/celebrations/themes/rain-control.js +1 -0
- package/public/js/celebrations/themes/sparkler-font-data.js +1 -0
- package/public/js/celebrations/themes/sparkler-font.js +1 -0
- package/public/js/celebrations/themes/sparkler-writing.js +1 -0
- package/public/js/celebrations/themes/summer-garden.js +1 -0
- package/public/js/celebrations/themes/winter.js +1 -0
- package/public/js/celebrations/trait-data.mjs +1 -1
- package/public/js/effects.js +1 -1
- package/scripts/build.js +4 -0
- package/server/services/markdown.js +5 -2
- package/server/templates/page.html +1 -1
|
@@ -0,0 +1,1017 @@
|
|
|
1
|
+
# Pro Documentation Implementation Plan
|
|
2
|
+
|
|
3
|
+
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
|
4
|
+
|
|
5
|
+
**Goal:** Add a Pro documentation section - four public `/resources/pro/` pages (index, Views, Actions, CTA shortcode) plus a single tabbed "Pro Documentation" admin panel under `#/pro/docs`.
|
|
6
|
+
|
|
7
|
+
**Architecture:** Public pages are Markdown files following the existing resources pattern (hero + content + back link). The admin panel is a static HTML template with three tabs wired by a minimal JS view - mirrors the `documentationView` pattern exactly (templateUrl + onMount with icons + syntax scan).
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** Markdown pages (Domma shortcodes), Domma admin SPA (templateUrl views, E.tabs, Domma.syntax.scan), sidebar-config.js, views/index.js, app.js routes.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Task 1: Public - Pro section index page
|
|
14
|
+
|
|
15
|
+
**Files:**
|
|
16
|
+
- Create: `content/pages/resources/pro/index.md`
|
|
17
|
+
|
|
18
|
+
**Step 1: Create the Pro landing page**
|
|
19
|
+
|
|
20
|
+
```markdown
|
|
21
|
+
---
|
|
22
|
+
title: Pro Features
|
|
23
|
+
slug: pro
|
|
24
|
+
description: >-
|
|
25
|
+
Pro features for Domma CMS - Views, Actions, and CTA shortcodes.
|
|
26
|
+
Requires MongoDB.
|
|
27
|
+
layout: default
|
|
28
|
+
status: published
|
|
29
|
+
sortOrder: 20
|
|
30
|
+
showInNav: false
|
|
31
|
+
sidebar: false
|
|
32
|
+
seo:
|
|
33
|
+
title: Pro Features - Resources
|
|
34
|
+
description: Domma CMS Pro features reference
|
|
35
|
+
createdAt: '2026-03-09T00:00:00.000Z'
|
|
36
|
+
updatedAt: '2026-03-09T00:00:00.000Z'
|
|
37
|
+
tags: []
|
|
38
|
+
category: null
|
|
39
|
+
visibility: public
|
|
40
|
+
dconfig: null
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
[hero variant="dark" size="sm" fullwidth="true" twinkle twinkle-count="20" blobs]
|
|
44
|
+
|
|
45
|
+
# Pro Features
|
|
46
|
+
|
|
47
|
+
Advanced features for Domma CMS requiring a MongoDB connection.
|
|
48
|
+
|
|
49
|
+
[/hero]
|
|
50
|
+
|
|
51
|
+
[badge style="warning"]Pro - requires MongoDB[/badge]
|
|
52
|
+
|
|
53
|
+
Pro features use MongoDB as a storage backend. A named connection must be configured in `config/connections.json` before creating Views or Actions.
|
|
54
|
+
|
|
55
|
+
[grid cols="3" gap="4"]
|
|
56
|
+
[col]
|
|
57
|
+
[card title="Views"]
|
|
58
|
+
MongoDB aggregation pipelines exposed as named, role-gated endpoints. Filter, join, sort, and reshape your collection data.
|
|
59
|
+
|
|
60
|
+
[Read more →](/resources/pro/views)
|
|
61
|
+
[/card]
|
|
62
|
+
[/col]
|
|
63
|
+
[col]
|
|
64
|
+
[card title="Actions"]
|
|
65
|
+
Multi-step operations on collection entries - update fields, send webhooks, fire emails, move or delete entries - triggered manually or via the `[cta]` shortcode.
|
|
66
|
+
|
|
67
|
+
[Read more →](/resources/pro/actions)
|
|
68
|
+
[/card]
|
|
69
|
+
[/col]
|
|
70
|
+
[col]
|
|
71
|
+
[card title="CTA Shortcode"]
|
|
72
|
+
Place action-trigger buttons anywhere in your Markdown content. Works standalone or integrated with the `[collection]` shortcode for per-entry buttons.
|
|
73
|
+
|
|
74
|
+
[Read more →](/resources/pro/cta)
|
|
75
|
+
[/card]
|
|
76
|
+
[/col]
|
|
77
|
+
[/grid]
|
|
78
|
+
|
|
79
|
+
← [Back to Resources](/resources)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Step 2: Verify the page renders**
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
curl -s http://localhost:4096/resources/pro | grep -c "Pro Features"
|
|
86
|
+
```
|
|
87
|
+
Expected: `1` (or more)
|
|
88
|
+
|
|
89
|
+
**Step 3: Commit**
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
git add content/pages/resources/pro/index.md
|
|
93
|
+
git commit -m "feat: add /resources/pro landing page"
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Task 2: Public - Views reference page
|
|
99
|
+
|
|
100
|
+
**Files:**
|
|
101
|
+
- Create: `content/pages/resources/pro/views.md`
|
|
102
|
+
|
|
103
|
+
**Step 1: Create the Views page**
|
|
104
|
+
|
|
105
|
+
```markdown
|
|
106
|
+
---
|
|
107
|
+
title: Views
|
|
108
|
+
slug: views
|
|
109
|
+
description: >-
|
|
110
|
+
MongoDB aggregation pipeline Views - filter, join, and reshape collection
|
|
111
|
+
data with role-gated public endpoints.
|
|
112
|
+
layout: default
|
|
113
|
+
status: published
|
|
114
|
+
sortOrder: 21
|
|
115
|
+
showInNav: false
|
|
116
|
+
sidebar: false
|
|
117
|
+
seo:
|
|
118
|
+
title: Views - Pro Features
|
|
119
|
+
description: Domma CMS Views reference
|
|
120
|
+
createdAt: '2026-03-09T00:00:00.000Z'
|
|
121
|
+
updatedAt: '2026-03-09T00:00:00.000Z'
|
|
122
|
+
tags: []
|
|
123
|
+
category: null
|
|
124
|
+
visibility: public
|
|
125
|
+
dconfig: null
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
[hero variant="dark" size="sm" fullwidth="true" twinkle twinkle-count="20" blobs]
|
|
129
|
+
|
|
130
|
+
# Views
|
|
131
|
+
|
|
132
|
+
[/hero]
|
|
133
|
+
|
|
134
|
+
[badge style="warning"]Pro - requires MongoDB[/badge]
|
|
135
|
+
|
|
136
|
+
A **View** is a saved MongoDB aggregation pipeline that runs against a collection and returns shaped results. Views are defined in the admin under **Data → Views** and exposed via a REST endpoint that respects role-level access and optional row-level filtering.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Creating a View
|
|
141
|
+
|
|
142
|
+
Go to **Data → Views → New View** and fill in:
|
|
143
|
+
|
|
144
|
+
| Field | Description |
|
|
145
|
+
|-------|-------------|
|
|
146
|
+
| **Title** | Human-readable name shown in the admin |
|
|
147
|
+
| **Slug** | URL-safe identifier - auto-generated from the title |
|
|
148
|
+
| **Description** | Optional notes about what this View returns |
|
|
149
|
+
| **Source Collection** | The primary collection the pipeline runs against |
|
|
150
|
+
| **Connection** | MongoDB connection name from `config/connections.json` (default: `default`) |
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Pipeline Stages
|
|
155
|
+
|
|
156
|
+
Switch to the **Pipeline** tab to add aggregation stages. Each stage is a JSON object using standard MongoDB aggregation syntax.
|
|
157
|
+
|
|
158
|
+
### Allowed stages
|
|
159
|
+
|
|
160
|
+
| Stage | Purpose |
|
|
161
|
+
|-------|---------|
|
|
162
|
+
| `$match` | Filter documents by field values |
|
|
163
|
+
| `$sort` | Order results by one or more fields |
|
|
164
|
+
| `$project` | Include, exclude, or rename fields |
|
|
165
|
+
| `$lookup` | Join data from another collection |
|
|
166
|
+
| `$unwind` | Flatten an array field into separate documents |
|
|
167
|
+
| `$addFields` | Compute and add new fields |
|
|
168
|
+
| `$group` | Aggregate documents (count, sum, etc.) |
|
|
169
|
+
| `$limit` | Cap the number of results |
|
|
170
|
+
| `$skip` | Skip N results (useful for manual pagination) |
|
|
171
|
+
| `$count` | Return a document count |
|
|
172
|
+
|
|
173
|
+
Stages `$out`, `$merge`, `$function`, `$accumulator`, and `$graphLookup` are **blocked** for security.
|
|
174
|
+
|
|
175
|
+
### Collection naming
|
|
176
|
+
|
|
177
|
+
The pipeline always runs on the MongoDB collection `cms_{slug}` - e.g. the `feedback` collection is stored as `cms_feedback`. Use this prefix when writing `$lookup` joins.
|
|
178
|
+
|
|
179
|
+
### Example pipeline - active users with submission count
|
|
180
|
+
|
|
181
|
+
```json
|
|
182
|
+
[
|
|
183
|
+
{ "$match": { "data.isActive": true } },
|
|
184
|
+
{
|
|
185
|
+
"$lookup": {
|
|
186
|
+
"from": "cms_feedback",
|
|
187
|
+
"localField": "_id",
|
|
188
|
+
"foreignField": "data.userId",
|
|
189
|
+
"as": "submissions"
|
|
190
|
+
}
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
"$addFields": {
|
|
194
|
+
"submissionCount": { "$size": "$submissions" }
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
{ "$project": { "data.name": 1, "data.email": 1, "submissionCount": 1 } },
|
|
198
|
+
{ "$sort": { "submissionCount": -1 } }
|
|
199
|
+
]
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## Display Settings
|
|
205
|
+
|
|
206
|
+
The **Display** tab controls how results appear in the admin preview and public endpoint:
|
|
207
|
+
|
|
208
|
+
| Field | Description |
|
|
209
|
+
|-------|-------------|
|
|
210
|
+
| **Display Mode** | `table` (default) or `list` |
|
|
211
|
+
| **Page Size** | Rows per page in the table (default 25) |
|
|
212
|
+
| **Column Definitions** | JSON array: `[{"key":"data.name","label":"Name"}]` - `key` is dot-notation path into each result document |
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## Access Control
|
|
217
|
+
|
|
218
|
+
The **Access** tab controls who can call this View:
|
|
219
|
+
|
|
220
|
+
- **Allowed Roles** - tick which roles can call `GET /api/views/:slug/public`
|
|
221
|
+
- **Public** - when checked, no authentication is required at all
|
|
222
|
+
- **Row-Level Access** - when enabled, each user only sees entries they own or are assigned to (admins always see everything)
|
|
223
|
+
|
|
224
|
+
### Row-level modes
|
|
225
|
+
|
|
226
|
+
| Mode | Behaviour |
|
|
227
|
+
|------|-----------|
|
|
228
|
+
| **Owner** | Only entries whose `meta.createdBy` matches the current user |
|
|
229
|
+
| **Field Match** | A specified field on the entry must match a property of the current user (e.g. `assigned_to` = `user.id`) |
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## Endpoints
|
|
234
|
+
|
|
235
|
+
| Method | URL | Auth |
|
|
236
|
+
|--------|-----|------|
|
|
237
|
+
| `GET` | `/api/views` | Admin / manager |
|
|
238
|
+
| `POST` | `/api/views` | Admin / manager |
|
|
239
|
+
| `GET` | `/api/views/:slug` | Admin / manager |
|
|
240
|
+
| `PUT` | `/api/views/:slug` | Admin / manager |
|
|
241
|
+
| `DELETE` | `/api/views/:slug` | Admin / manager |
|
|
242
|
+
| `GET` | `/api/views/:slug/execute` | Admin (preview) |
|
|
243
|
+
| `GET` | `/api/views/:slug/public` | Role-gated (see Access tab) |
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
← [Back to Pro Features](/resources/pro)
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
**Step 2: Verify**
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
curl -s http://localhost:4096/resources/pro/views | grep -c "aggregation"
|
|
254
|
+
```
|
|
255
|
+
Expected: `1` (or more)
|
|
256
|
+
|
|
257
|
+
**Step 3: Commit**
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
git add content/pages/resources/pro/views.md
|
|
261
|
+
git commit -m "feat: add /resources/pro/views reference page"
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## Task 3: Public - Actions reference page
|
|
267
|
+
|
|
268
|
+
**Files:**
|
|
269
|
+
- Create: `content/pages/resources/pro/actions.md`
|
|
270
|
+
|
|
271
|
+
**Step 1: Create the Actions page**
|
|
272
|
+
|
|
273
|
+
```markdown
|
|
274
|
+
---
|
|
275
|
+
title: Actions
|
|
276
|
+
slug: actions
|
|
277
|
+
description: >-
|
|
278
|
+
Multi-step Actions on collection entries - update fields, send webhooks,
|
|
279
|
+
fire emails, and more.
|
|
280
|
+
layout: default
|
|
281
|
+
status: published
|
|
282
|
+
sortOrder: 22
|
|
283
|
+
showInNav: false
|
|
284
|
+
sidebar: false
|
|
285
|
+
seo:
|
|
286
|
+
title: Actions - Pro Features
|
|
287
|
+
description: Domma CMS Actions reference
|
|
288
|
+
createdAt: '2026-03-09T00:00:00.000Z'
|
|
289
|
+
updatedAt: '2026-03-09T00:00:00.000Z'
|
|
290
|
+
tags: []
|
|
291
|
+
category: null
|
|
292
|
+
visibility: public
|
|
293
|
+
dconfig: null
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
[hero variant="dark" size="sm" fullwidth="true" twinkle twinkle-count="20" blobs]
|
|
297
|
+
|
|
298
|
+
# Actions
|
|
299
|
+
|
|
300
|
+
[/hero]
|
|
301
|
+
|
|
302
|
+
[badge style="warning"]Pro - requires MongoDB[/badge]
|
|
303
|
+
|
|
304
|
+
An **Action** is a named sequence of steps that runs against a single collection entry. Actions are defined in the admin under **Data → Actions** and can be triggered manually from the entry list, or from any public page via the `[cta]` shortcode.
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
## Creating an Action
|
|
309
|
+
|
|
310
|
+
Go to **Data → Actions → New Action** and fill in:
|
|
311
|
+
|
|
312
|
+
| Field | Description |
|
|
313
|
+
|-------|-------------|
|
|
314
|
+
| **Title** | Human-readable name (e.g. *Approve Application*) |
|
|
315
|
+
| **Slug** | URL-safe identifier - auto-generated from the title |
|
|
316
|
+
| **Description** | Optional notes |
|
|
317
|
+
| **Target Collection** | The collection this action operates on |
|
|
318
|
+
|
|
319
|
+
---
|
|
320
|
+
|
|
321
|
+
## Trigger Settings
|
|
322
|
+
|
|
323
|
+
The **Trigger** tab controls how the Action is invoked from the admin:
|
|
324
|
+
|
|
325
|
+
| Field | Description |
|
|
326
|
+
|-------|-------------|
|
|
327
|
+
| **Trigger Type** | Currently: `Manual` (button in the entry list) |
|
|
328
|
+
| **Button Label** | Label shown on the trigger button (default: `Run`) |
|
|
329
|
+
| **Button Icon** | Domma icon name (e.g. `check-circle`, `zap`, `send`) |
|
|
330
|
+
| **Confirmation Message** | Optional prompt before execution - leave blank to skip |
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## Steps
|
|
335
|
+
|
|
336
|
+
The **Steps** tab defines what the Action does. Steps run in order. If a step fails, execution stops and a partial result is returned indicating how many steps completed.
|
|
337
|
+
|
|
338
|
+
### Step types
|
|
339
|
+
|
|
340
|
+
#### `updateField`
|
|
341
|
+
|
|
342
|
+
Sets a field on the entry to a new value. Supports template variables.
|
|
343
|
+
|
|
344
|
+
```json
|
|
345
|
+
{
|
|
346
|
+
"field": "status",
|
|
347
|
+
"value": "approved"
|
|
348
|
+
}
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
#### `deleteEntry`
|
|
352
|
+
|
|
353
|
+
Permanently deletes the target entry. No additional config needed.
|
|
354
|
+
|
|
355
|
+
#### `moveToCollection`
|
|
356
|
+
|
|
357
|
+
Moves the entry to a different collection (copies data, then deletes from source).
|
|
358
|
+
|
|
359
|
+
```json
|
|
360
|
+
{
|
|
361
|
+
"targetCollection": "approved-applications"
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
#### `webhook`
|
|
366
|
+
|
|
367
|
+
POSTs the entry data to an external URL.
|
|
368
|
+
|
|
369
|
+
```json
|
|
370
|
+
{
|
|
371
|
+
"url": "https://hooks.example.com/notify",
|
|
372
|
+
"headers": { "X-Secret": "{{env.CMS_PUBLIC_HOOK_SECRET}}" }
|
|
373
|
+
}
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
#### `email`
|
|
377
|
+
|
|
378
|
+
Sends an email via the configured SMTP server (set in **Settings → Email / SMTP**).
|
|
379
|
+
|
|
380
|
+
```json
|
|
381
|
+
{
|
|
382
|
+
"to": "{{entry.data.email}}",
|
|
383
|
+
"subject": "Your application was approved",
|
|
384
|
+
"body": "Hi {{entry.data.name}},\n\nYour application has been approved."
|
|
385
|
+
}
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
## Template Variables
|
|
391
|
+
|
|
392
|
+
All step field values support template interpolation using `{{...}}` syntax:
|
|
393
|
+
|
|
394
|
+
| Variable | Value |
|
|
395
|
+
|----------|-------|
|
|
396
|
+
| `{{entry.data.fieldName}}` | Any field from the target entry |
|
|
397
|
+
| `{{entry.id}}` | The entry's UUID |
|
|
398
|
+
| `{{now}}` | Current timestamp in ISO 8601 format |
|
|
399
|
+
| `{{user.name}}` | Name of the user who triggered the Action |
|
|
400
|
+
| `{{user.email}}` | Email of the triggering user |
|
|
401
|
+
| `{{user.id}}` | UUID of the triggering user |
|
|
402
|
+
| `{{env.CMS_PUBLIC_*}}` | Public environment variables (prefixed `CMS_PUBLIC_`) |
|
|
403
|
+
|
|
404
|
+
---
|
|
405
|
+
|
|
406
|
+
## Access Control
|
|
407
|
+
|
|
408
|
+
The **Access** tab works identically to Views:
|
|
409
|
+
|
|
410
|
+
- **Allowed Roles** - who can call `POST /api/actions/:slug/public`
|
|
411
|
+
- **Row-Level Access** - restrict execution to entries owned by or assigned to the current user
|
|
412
|
+
|
|
413
|
+
---
|
|
414
|
+
|
|
415
|
+
## Endpoints
|
|
416
|
+
|
|
417
|
+
| Method | URL | Auth |
|
|
418
|
+
|--------|-----|------|
|
|
419
|
+
| `GET` | `/api/actions` | Admin / manager |
|
|
420
|
+
| `POST` | `/api/actions` | Admin / manager |
|
|
421
|
+
| `GET` | `/api/actions/:slug` | Admin / manager |
|
|
422
|
+
| `PUT` | `/api/actions/:slug` | Admin / manager |
|
|
423
|
+
| `DELETE` | `/api/actions/:slug` | Admin / manager |
|
|
424
|
+
| `POST` | `/api/actions/:slug/execute` | Admin (test run) |
|
|
425
|
+
| `POST` | `/api/actions/:slug/public` | Role-gated (see Access tab) |
|
|
426
|
+
|
|
427
|
+
The public endpoint expects a JSON body: `{ "entryId": "uuid-of-entry" }`
|
|
428
|
+
|
|
429
|
+
---
|
|
430
|
+
|
|
431
|
+
← [Back to Pro Features](/resources/pro)
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
**Step 2: Verify**
|
|
435
|
+
|
|
436
|
+
```bash
|
|
437
|
+
curl -s http://localhost:4096/resources/pro/actions | grep -c "updateField"
|
|
438
|
+
```
|
|
439
|
+
Expected: `1` (or more)
|
|
440
|
+
|
|
441
|
+
**Step 3: Commit**
|
|
442
|
+
|
|
443
|
+
```bash
|
|
444
|
+
git add content/pages/resources/pro/actions.md
|
|
445
|
+
git commit -m "feat: add /resources/pro/actions reference page"
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
---
|
|
449
|
+
|
|
450
|
+
## Task 4: Public - CTA shortcode reference page
|
|
451
|
+
|
|
452
|
+
**Files:**
|
|
453
|
+
- Create: `content/pages/resources/pro/cta.md`
|
|
454
|
+
|
|
455
|
+
**Step 1: Create the CTA page**
|
|
456
|
+
|
|
457
|
+
```markdown
|
|
458
|
+
---
|
|
459
|
+
title: CTA Shortcode
|
|
460
|
+
slug: cta
|
|
461
|
+
description: >-
|
|
462
|
+
Place Action-trigger buttons anywhere in your Markdown content using the
|
|
463
|
+
[cta] shortcode.
|
|
464
|
+
layout: default
|
|
465
|
+
status: published
|
|
466
|
+
sortOrder: 23
|
|
467
|
+
showInNav: false
|
|
468
|
+
sidebar: false
|
|
469
|
+
seo:
|
|
470
|
+
title: CTA Shortcode - Pro Features
|
|
471
|
+
description: Domma CMS CTA shortcode reference
|
|
472
|
+
createdAt: '2026-03-09T00:00:00.000Z'
|
|
473
|
+
updatedAt: '2026-03-09T00:00:00.000Z'
|
|
474
|
+
tags: []
|
|
475
|
+
category: null
|
|
476
|
+
visibility: public
|
|
477
|
+
dconfig: null
|
|
478
|
+
---
|
|
479
|
+
|
|
480
|
+
[hero variant="dark" size="sm" fullwidth="true" twinkle twinkle-count="20" blobs]
|
|
481
|
+
|
|
482
|
+
# CTA Shortcode
|
|
483
|
+
|
|
484
|
+
[/hero]
|
|
485
|
+
|
|
486
|
+
The `[cta]` shortcode renders a button that triggers a named Action against a specific entry. The button uses the logged-in user's JWT to authenticate the request - no separate login is required if the user is already signed in to the admin.
|
|
487
|
+
|
|
488
|
+
---
|
|
489
|
+
|
|
490
|
+
## Syntax
|
|
491
|
+
|
|
492
|
+
Two forms are supported:
|
|
493
|
+
|
|
494
|
+
**Wrapping form** - button label comes from the body:
|
|
495
|
+
|
|
496
|
+
```
|
|
497
|
+
[cta action="slug" entry="entry-id"]Button label[/cta]
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
**Self-closing form** - button label from `label` attribute:
|
|
501
|
+
|
|
502
|
+
```
|
|
503
|
+
[cta action="slug" entry="entry-id" label="Button label" /]
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
---
|
|
507
|
+
|
|
508
|
+
## Attributes
|
|
509
|
+
|
|
510
|
+
| Attribute | Required | Default | Description |
|
|
511
|
+
|-----------|----------|---------|-------------|
|
|
512
|
+
| `action` | Yes | - | Slug of the Action to execute |
|
|
513
|
+
| `entry` | Yes | - | UUID of the entry to act on |
|
|
514
|
+
| `label` | No | `"Run"` | Button text (self-closing form only) |
|
|
515
|
+
| `style` | No | `"primary"` | Button variant: `primary`, `secondary`, `ghost`, `danger` |
|
|
516
|
+
| `icon` | No | - | Domma icon name shown before the label |
|
|
517
|
+
| `size` | No | - | Button size: `sm`, `md`, `lg` |
|
|
518
|
+
| `confirm` | No | - | Confirmation prompt text - shown before executing |
|
|
519
|
+
|
|
520
|
+
---
|
|
521
|
+
|
|
522
|
+
## Examples
|
|
523
|
+
|
|
524
|
+
### Basic button
|
|
525
|
+
|
|
526
|
+
```
|
|
527
|
+
[cta action="approve-application" entry="abc-123"]Approve[/cta]
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
### With icon and confirmation
|
|
531
|
+
|
|
532
|
+
```
|
|
533
|
+
[cta action="approve-application" entry="abc-123" icon="check" style="primary" confirm="Approve this application?"]Approve[/cta]
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
### Danger button with confirmation
|
|
537
|
+
|
|
538
|
+
```
|
|
539
|
+
[cta action="delete-entry" entry="abc-123" style="danger" confirm="Permanently delete this entry?"]Delete[/cta]
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
### Self-closing form
|
|
543
|
+
|
|
544
|
+
```
|
|
545
|
+
[cta action="send-welcome-email" entry="abc-123" label="Send welcome email" icon="send" /]
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
---
|
|
549
|
+
|
|
550
|
+
## Collection Integration
|
|
551
|
+
|
|
552
|
+
Add per-entry CTA buttons to any `[collection]` shortcode by adding `cta` and related attributes:
|
|
553
|
+
|
|
554
|
+
```
|
|
555
|
+
[collection slug="applications" display="cards" title-field="name"
|
|
556
|
+
cta="approve-application"
|
|
557
|
+
cta-label="Approve"
|
|
558
|
+
cta-icon="check"
|
|
559
|
+
cta-style="primary"
|
|
560
|
+
cta-confirm="Approve this application?" /]
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
### Collection CTA attributes
|
|
564
|
+
|
|
565
|
+
| Attribute | Default | Description |
|
|
566
|
+
|-----------|---------|-------------|
|
|
567
|
+
| `cta` | - | Action slug - enables per-entry buttons |
|
|
568
|
+
| `cta-label` | `"Run"` | Button label |
|
|
569
|
+
| `cta-icon` | - | Domma icon name |
|
|
570
|
+
| `cta-style` | `"primary"` | Button variant |
|
|
571
|
+
| `cta-confirm` | - | Confirmation prompt |
|
|
572
|
+
|
|
573
|
+
All three display modes support CTA buttons: **cards** (footer), **list** (inline), and **table** (dedicated column).
|
|
574
|
+
|
|
575
|
+
---
|
|
576
|
+
|
|
577
|
+
## Authentication
|
|
578
|
+
|
|
579
|
+
The button reads the user's token from `S.get('auth_token')` - the same token used by the admin panel. If the user is not logged in, clicking the button shows a warning toast:
|
|
580
|
+
|
|
581
|
+
> *"Please log in to perform this action."*
|
|
582
|
+
|
|
583
|
+
The Action's **Access** tab controls which roles are allowed to trigger it via the public endpoint.
|
|
584
|
+
|
|
585
|
+
---
|
|
586
|
+
|
|
587
|
+
← [Back to Pro Features](/resources/pro)
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
**Step 2: Verify**
|
|
591
|
+
|
|
592
|
+
```bash
|
|
593
|
+
curl -s http://localhost:4096/resources/pro/cta | grep -c "cta-label"
|
|
594
|
+
```
|
|
595
|
+
Expected: `1` (or more)
|
|
596
|
+
|
|
597
|
+
**Step 3: Commit**
|
|
598
|
+
|
|
599
|
+
```bash
|
|
600
|
+
git add content/pages/resources/pro/cta.md
|
|
601
|
+
git commit -m "feat: add /resources/pro/cta shortcode reference page"
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
---
|
|
605
|
+
|
|
606
|
+
## Task 5: Update Resources index - add Pro card
|
|
607
|
+
|
|
608
|
+
**Files:**
|
|
609
|
+
- Modify: `content/pages/resources/index.md`
|
|
610
|
+
|
|
611
|
+
**Step 1: Add a Pro Features card to the grid**
|
|
612
|
+
|
|
613
|
+
In `content/pages/resources/index.md`, add a new `[col]` + `[card]` block inside the existing `[grid cols="3" gap="4"]` - after the last card (Dependencies) and before `[/grid]`:
|
|
614
|
+
|
|
615
|
+
```
|
|
616
|
+
[col]
|
|
617
|
+
[card title="Pro Features"]
|
|
618
|
+
Views, Actions, and the CTA shortcode - advanced features powered by MongoDB. [badge style="warning"]Pro[/badge]
|
|
619
|
+
|
|
620
|
+
[Read more →](/resources/pro)
|
|
621
|
+
[/card]
|
|
622
|
+
[/col]
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
**Step 2: Verify the Resources index still renders**
|
|
626
|
+
|
|
627
|
+
```bash
|
|
628
|
+
curl -s http://localhost:4096/resources | grep -c "Pro Features"
|
|
629
|
+
```
|
|
630
|
+
Expected: `1`
|
|
631
|
+
|
|
632
|
+
**Step 3: Commit**
|
|
633
|
+
|
|
634
|
+
```bash
|
|
635
|
+
git add content/pages/resources/index.md
|
|
636
|
+
git commit -m "feat: add Pro Features card to resources index"
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
---
|
|
640
|
+
|
|
641
|
+
## Task 6: Admin - Pro Documentation view JS + HTML template
|
|
642
|
+
|
|
643
|
+
**Files:**
|
|
644
|
+
- Create: `admin/js/views/pro-docs.js`
|
|
645
|
+
- Create: `admin/js/templates/pro-docs.html`
|
|
646
|
+
|
|
647
|
+
**Step 1: Create the view module**
|
|
648
|
+
|
|
649
|
+
`admin/js/views/pro-docs.js`:
|
|
650
|
+
|
|
651
|
+
```js
|
|
652
|
+
/**
|
|
653
|
+
* Pro Documentation View
|
|
654
|
+
* Reference for Pro-only features: Views, Actions, and the CTA shortcode.
|
|
655
|
+
*/
|
|
656
|
+
export const proDocsView = {
|
|
657
|
+
templateUrl: '/admin/js/templates/pro-docs.html',
|
|
658
|
+
|
|
659
|
+
async onMount($container) {
|
|
660
|
+
E.tabs($container.find('#pro-docs-tabs').get(0));
|
|
661
|
+
Domma.icons.scan();
|
|
662
|
+
Domma.syntax.scan();
|
|
663
|
+
}
|
|
664
|
+
};
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
**Step 2: Create the template**
|
|
668
|
+
|
|
669
|
+
`admin/js/templates/pro-docs.html` - a three-tab layout (Views, Actions, CTA Shortcode). Each tab is a collapsible-card reference section matching the style of `documentation.html`.
|
|
670
|
+
|
|
671
|
+
```html
|
|
672
|
+
<div class="view-header">
|
|
673
|
+
<h1><span data-icon="zap"></span> Pro Documentation</h1>
|
|
674
|
+
</div>
|
|
675
|
+
|
|
676
|
+
<div class="tabs" id="pro-docs-tabs">
|
|
677
|
+
<div class="tab-list">
|
|
678
|
+
<button class="tab-item active">Views</button>
|
|
679
|
+
<button class="tab-item">Actions</button>
|
|
680
|
+
<button class="tab-item">CTA Shortcode</button>
|
|
681
|
+
</div>
|
|
682
|
+
<div class="tab-content">
|
|
683
|
+
|
|
684
|
+
<!-- ── Views tab ─────────────────────────────────────── -->
|
|
685
|
+
<div class="tab-panel active">
|
|
686
|
+
|
|
687
|
+
<div class="card card-collapsible mb-4">
|
|
688
|
+
<div class="card-header" role="button" tabindex="0">
|
|
689
|
+
<div class="card-header-content"><h2><span data-icon="eye"></span> What is a View?</h2></div>
|
|
690
|
+
<span class="card-collapse-icon" data-icon="chevron-down"></span>
|
|
691
|
+
</div>
|
|
692
|
+
<div class="card-body docs-body">
|
|
693
|
+
<p>A <strong>View</strong> is a saved MongoDB aggregation pipeline that runs against a collection and returns shaped results. Views are created under <strong>Data → Views</strong> and exposed via a REST endpoint that respects role-level and row-level access.</p>
|
|
694
|
+
<p>Views require a MongoDB connection configured in <code>config/connections.json</code>.</p>
|
|
695
|
+
</div>
|
|
696
|
+
</div>
|
|
697
|
+
|
|
698
|
+
<div class="card card-collapsible mb-4">
|
|
699
|
+
<div class="card-header" role="button" tabindex="0">
|
|
700
|
+
<div class="card-header-content"><h2><span data-icon="layers"></span> Allowed Pipeline Stages</h2></div>
|
|
701
|
+
<span class="card-collapse-icon" data-icon="chevron-down"></span>
|
|
702
|
+
</div>
|
|
703
|
+
<div class="card-body docs-body">
|
|
704
|
+
<table class="table table-sm">
|
|
705
|
+
<thead><tr><th>Stage</th><th>Purpose</th></tr></thead>
|
|
706
|
+
<tbody>
|
|
707
|
+
<tr><td><code>$match</code></td><td>Filter documents by field values</td></tr>
|
|
708
|
+
<tr><td><code>$sort</code></td><td>Order results</td></tr>
|
|
709
|
+
<tr><td><code>$project</code></td><td>Include, exclude, or rename fields</td></tr>
|
|
710
|
+
<tr><td><code>$lookup</code></td><td>Join from another collection</td></tr>
|
|
711
|
+
<tr><td><code>$unwind</code></td><td>Flatten an array field</td></tr>
|
|
712
|
+
<tr><td><code>$addFields</code></td><td>Compute new fields</td></tr>
|
|
713
|
+
<tr><td><code>$group</code></td><td>Aggregate (count, sum, etc.)</td></tr>
|
|
714
|
+
<tr><td><code>$limit</code></td><td>Cap results</td></tr>
|
|
715
|
+
<tr><td><code>$skip</code></td><td>Skip N results</td></tr>
|
|
716
|
+
<tr><td><code>$count</code></td><td>Return a document count</td></tr>
|
|
717
|
+
</tbody>
|
|
718
|
+
</table>
|
|
719
|
+
<p class="text-muted" style="margin-top:.75rem;">Blocked: <code>$out</code>, <code>$merge</code>, <code>$function</code>, <code>$accumulator</code>, <code>$graphLookup</code></p>
|
|
720
|
+
<p>Collections are prefixed <code>cms_</code> in MongoDB - use this prefix in <code>$lookup</code> <code>from</code> values.</p>
|
|
721
|
+
</div>
|
|
722
|
+
</div>
|
|
723
|
+
|
|
724
|
+
<div class="card card-collapsible mb-4">
|
|
725
|
+
<div class="card-header" role="button" tabindex="0">
|
|
726
|
+
<div class="card-header-content"><h2><span data-icon="code"></span> Example Pipeline</h2></div>
|
|
727
|
+
<span class="card-collapse-icon" data-icon="chevron-down"></span>
|
|
728
|
+
</div>
|
|
729
|
+
<div class="card-body docs-body">
|
|
730
|
+
<p>Match active entries and count related submissions:</p>
|
|
731
|
+
<pre class="code-block"><code>[
|
|
732
|
+
{ "$match": { "data.isActive": true } },
|
|
733
|
+
{
|
|
734
|
+
"$lookup": {
|
|
735
|
+
"from": "cms_feedback",
|
|
736
|
+
"localField": "_id",
|
|
737
|
+
"foreignField": "data.userId",
|
|
738
|
+
"as": "submissions"
|
|
739
|
+
}
|
|
740
|
+
},
|
|
741
|
+
{ "$addFields": { "submissionCount": { "$size": "$submissions" } } },
|
|
742
|
+
{ "$project": { "data.name": 1, "data.email": 1, "submissionCount": 1 } },
|
|
743
|
+
{ "$sort": { "submissionCount": -1 } }
|
|
744
|
+
]</code></pre>
|
|
745
|
+
</div>
|
|
746
|
+
</div>
|
|
747
|
+
|
|
748
|
+
<div class="card card-collapsible mb-4">
|
|
749
|
+
<div class="card-header" role="button" tabindex="0">
|
|
750
|
+
<div class="card-header-content"><h2><span data-icon="lock"></span> Access Control</h2></div>
|
|
751
|
+
<span class="card-collapse-icon" data-icon="chevron-down"></span>
|
|
752
|
+
</div>
|
|
753
|
+
<div class="card-body docs-body">
|
|
754
|
+
<table class="table table-sm">
|
|
755
|
+
<thead><tr><th>Setting</th><th>Description</th></tr></thead>
|
|
756
|
+
<tbody>
|
|
757
|
+
<tr><td>Allowed Roles</td><td>Which roles can call <code>GET /api/views/:slug/public</code></td></tr>
|
|
758
|
+
<tr><td>Public</td><td>No authentication required when checked</td></tr>
|
|
759
|
+
<tr><td>Row-Level - Owner</td><td>User sees only entries they created</td></tr>
|
|
760
|
+
<tr><td>Row-Level - Field Match</td><td>A specified entry field must match a user property</td></tr>
|
|
761
|
+
</tbody>
|
|
762
|
+
</table>
|
|
763
|
+
</div>
|
|
764
|
+
</div>
|
|
765
|
+
|
|
766
|
+
</div><!-- /Views tab -->
|
|
767
|
+
|
|
768
|
+
<!-- ── Actions tab ───────────────────────────────────── -->
|
|
769
|
+
<div class="tab-panel">
|
|
770
|
+
|
|
771
|
+
<div class="card card-collapsible mb-4">
|
|
772
|
+
<div class="card-header" role="button" tabindex="0">
|
|
773
|
+
<div class="card-header-content"><h2><span data-icon="zap"></span> What is an Action?</h2></div>
|
|
774
|
+
<span class="card-collapse-icon" data-icon="chevron-down"></span>
|
|
775
|
+
</div>
|
|
776
|
+
<div class="card-body docs-body">
|
|
777
|
+
<p>An <strong>Action</strong> is a named sequence of steps that runs against a single collection entry. Actions are defined under <strong>Data → Actions</strong> and can be triggered from the entry list or via the <code>[cta]</code> shortcode on any public page.</p>
|
|
778
|
+
<p>Actions require a MongoDB connection configured in <code>config/connections.json</code>.</p>
|
|
779
|
+
<p>Steps run in order. If a step fails, execution stops and a partial result is returned with a <code>stepsCompleted</code> count.</p>
|
|
780
|
+
</div>
|
|
781
|
+
</div>
|
|
782
|
+
|
|
783
|
+
<div class="card card-collapsible mb-4">
|
|
784
|
+
<div class="card-header" role="button" tabindex="0">
|
|
785
|
+
<div class="card-header-content"><h2><span data-icon="list"></span> Step Types</h2></div>
|
|
786
|
+
<span class="card-collapse-icon" data-icon="chevron-down"></span>
|
|
787
|
+
</div>
|
|
788
|
+
<div class="card-body docs-body">
|
|
789
|
+
<table class="table table-sm">
|
|
790
|
+
<thead><tr><th>Type</th><th>What it does</th></tr></thead>
|
|
791
|
+
<tbody>
|
|
792
|
+
<tr><td><code>updateField</code></td><td>Sets a field on the entry to a new value</td></tr>
|
|
793
|
+
<tr><td><code>deleteEntry</code></td><td>Permanently deletes the target entry</td></tr>
|
|
794
|
+
<tr><td><code>moveToCollection</code></td><td>Moves the entry to a different collection</td></tr>
|
|
795
|
+
<tr><td><code>webhook</code></td><td>POSTs entry data to an external URL</td></tr>
|
|
796
|
+
<tr><td><code>email</code></td><td>Sends an email via the configured SMTP server</td></tr>
|
|
797
|
+
</tbody>
|
|
798
|
+
</table>
|
|
799
|
+
</div>
|
|
800
|
+
</div>
|
|
801
|
+
|
|
802
|
+
<div class="card card-collapsible mb-4">
|
|
803
|
+
<div class="card-header" role="button" tabindex="0">
|
|
804
|
+
<div class="card-header-content"><h2><span data-icon="tag"></span> Template Variables</h2></div>
|
|
805
|
+
<span class="card-collapse-icon" data-icon="chevron-down"></span>
|
|
806
|
+
</div>
|
|
807
|
+
<div class="card-body docs-body">
|
|
808
|
+
<p>All step field values support <code>{{...}}</code> interpolation:</p>
|
|
809
|
+
<table class="table table-sm">
|
|
810
|
+
<thead><tr><th>Variable</th><th>Value</th></tr></thead>
|
|
811
|
+
<tbody>
|
|
812
|
+
<tr><td><code>{{entry.data.fieldName}}</code></td><td>Any field from the target entry</td></tr>
|
|
813
|
+
<tr><td><code>{{entry.id}}</code></td><td>The entry's UUID</td></tr>
|
|
814
|
+
<tr><td><code>{{now}}</code></td><td>Current ISO 8601 timestamp</td></tr>
|
|
815
|
+
<tr><td><code>{{user.name}}</code></td><td>Name of the triggering user</td></tr>
|
|
816
|
+
<tr><td><code>{{user.email}}</code></td><td>Email of the triggering user</td></tr>
|
|
817
|
+
<tr><td><code>{{user.id}}</code></td><td>UUID of the triggering user</td></tr>
|
|
818
|
+
<tr><td><code>{{env.CMS_PUBLIC_*}}</code></td><td>Public environment variables</td></tr>
|
|
819
|
+
</tbody>
|
|
820
|
+
</table>
|
|
821
|
+
</div>
|
|
822
|
+
</div>
|
|
823
|
+
|
|
824
|
+
<div class="card card-collapsible mb-4">
|
|
825
|
+
<div class="card-header" role="button" tabindex="0">
|
|
826
|
+
<div class="card-header-content"><h2><span data-icon="code"></span> Step Examples</h2></div>
|
|
827
|
+
<span class="card-collapse-icon" data-icon="chevron-down"></span>
|
|
828
|
+
</div>
|
|
829
|
+
<div class="card-body docs-body">
|
|
830
|
+
<p><strong>updateField</strong> - mark an entry as approved:</p>
|
|
831
|
+
<pre class="code-block"><code>{ "field": "status", "value": "approved" }</code></pre>
|
|
832
|
+
<p><strong>webhook</strong> - notify an external service:</p>
|
|
833
|
+
<pre class="code-block"><code>{
|
|
834
|
+
"url": "https://hooks.example.com/notify",
|
|
835
|
+
"headers": { "X-Secret": "{{env.CMS_PUBLIC_HOOK_SECRET}}" }
|
|
836
|
+
}</code></pre>
|
|
837
|
+
<p><strong>email</strong> - send confirmation to applicant:</p>
|
|
838
|
+
<pre class="code-block"><code>{
|
|
839
|
+
"to": "{{entry.data.email}}",
|
|
840
|
+
"subject": "Your application was approved",
|
|
841
|
+
"body": "Hi {{entry.data.name}}, your application has been approved."
|
|
842
|
+
}</code></pre>
|
|
843
|
+
</div>
|
|
844
|
+
</div>
|
|
845
|
+
|
|
846
|
+
</div><!-- /Actions tab -->
|
|
847
|
+
|
|
848
|
+
<!-- ── CTA Shortcode tab ──────────────────────────────── -->
|
|
849
|
+
<div class="tab-panel">
|
|
850
|
+
|
|
851
|
+
<div class="card card-collapsible mb-4">
|
|
852
|
+
<div class="card-header" role="button" tabindex="0">
|
|
853
|
+
<div class="card-header-content"><h2><span data-icon="mouse-pointer"></span> What is the CTA shortcode?</h2></div>
|
|
854
|
+
<span class="card-collapse-icon" data-icon="chevron-down"></span>
|
|
855
|
+
</div>
|
|
856
|
+
<div class="card-body docs-body">
|
|
857
|
+
<p>The <code>[cta]</code> shortcode places an action-trigger button in any public page. Clicking it calls <code>POST /api/actions/:slug/public</code> with the entry ID, using the logged-in user's JWT.</p>
|
|
858
|
+
<p>If the user is not logged in, a warning toast is shown instead.</p>
|
|
859
|
+
</div>
|
|
860
|
+
</div>
|
|
861
|
+
|
|
862
|
+
<div class="card card-collapsible mb-4">
|
|
863
|
+
<div class="card-header" role="button" tabindex="0">
|
|
864
|
+
<div class="card-header-content"><h2><span data-icon="code"></span> Syntax & Attributes</h2></div>
|
|
865
|
+
<span class="card-collapse-icon" data-icon="chevron-down"></span>
|
|
866
|
+
</div>
|
|
867
|
+
<div class="card-body docs-body">
|
|
868
|
+
<p><strong>Wrapping form:</strong></p>
|
|
869
|
+
<pre class="code-block"><code>[cta action="slug" entry="entry-id" icon="check" confirm="Are you sure?"]Button label[/cta]</code></pre>
|
|
870
|
+
<p><strong>Self-closing form:</strong></p>
|
|
871
|
+
<pre class="code-block"><code>[cta action="slug" entry="entry-id" label="Button label" /]</code></pre>
|
|
872
|
+
<table class="table table-sm" style="margin-top:1rem;">
|
|
873
|
+
<thead><tr><th>Attribute</th><th>Required</th><th>Default</th><th>Description</th></tr></thead>
|
|
874
|
+
<tbody>
|
|
875
|
+
<tr><td><code>action</code></td><td>Yes</td><td>-</td><td>Action slug</td></tr>
|
|
876
|
+
<tr><td><code>entry</code></td><td>Yes</td><td>-</td><td>Entry UUID to act on</td></tr>
|
|
877
|
+
<tr><td><code>label</code></td><td>No</td><td><code>"Run"</code></td><td>Button text (self-closing only)</td></tr>
|
|
878
|
+
<tr><td><code>style</code></td><td>No</td><td><code>"primary"</code></td><td>primary · secondary · ghost · danger</td></tr>
|
|
879
|
+
<tr><td><code>icon</code></td><td>No</td><td>-</td><td>Domma icon name</td></tr>
|
|
880
|
+
<tr><td><code>size</code></td><td>No</td><td>-</td><td>sm · md · lg</td></tr>
|
|
881
|
+
<tr><td><code>confirm</code></td><td>No</td><td>-</td><td>Confirmation prompt before executing</td></tr>
|
|
882
|
+
</tbody>
|
|
883
|
+
</table>
|
|
884
|
+
</div>
|
|
885
|
+
</div>
|
|
886
|
+
|
|
887
|
+
<div class="card card-collapsible mb-4">
|
|
888
|
+
<div class="card-header" role="button" tabindex="0">
|
|
889
|
+
<div class="card-header-content"><h2><span data-icon="grid"></span> Collection Integration</h2></div>
|
|
890
|
+
<span class="card-collapse-icon" data-icon="chevron-down"></span>
|
|
891
|
+
</div>
|
|
892
|
+
<div class="card-body docs-body">
|
|
893
|
+
<p>Add per-entry buttons to any <code>[collection]</code> shortcode:</p>
|
|
894
|
+
<pre class="code-block"><code>[collection slug="applications" display="cards" title-field="name"
|
|
895
|
+
cta="approve-application"
|
|
896
|
+
cta-label="Approve"
|
|
897
|
+
cta-icon="check"
|
|
898
|
+
cta-style="primary"
|
|
899
|
+
cta-confirm="Approve this application?" /]</code></pre>
|
|
900
|
+
<table class="table table-sm" style="margin-top:1rem;">
|
|
901
|
+
<thead><tr><th>Attribute</th><th>Default</th><th>Description</th></tr></thead>
|
|
902
|
+
<tbody>
|
|
903
|
+
<tr><td><code>cta</code></td><td>-</td><td>Action slug - enables per-entry buttons</td></tr>
|
|
904
|
+
<tr><td><code>cta-label</code></td><td><code>"Run"</code></td><td>Button label</td></tr>
|
|
905
|
+
<tr><td><code>cta-icon</code></td><td>-</td><td>Domma icon name</td></tr>
|
|
906
|
+
<tr><td><code>cta-style</code></td><td><code>"primary"</code></td><td>Button variant</td></tr>
|
|
907
|
+
<tr><td><code>cta-confirm</code></td><td>-</td><td>Confirmation prompt</td></tr>
|
|
908
|
+
</tbody>
|
|
909
|
+
</table>
|
|
910
|
+
<p>All three display modes support CTA buttons: <strong>cards</strong> (card footer), <strong>list</strong> (inline), <strong>table</strong> (dedicated column).</p>
|
|
911
|
+
</div>
|
|
912
|
+
</div>
|
|
913
|
+
|
|
914
|
+
<div class="card card-collapsible mb-4">
|
|
915
|
+
<div class="card-header" role="button" tabindex="0">
|
|
916
|
+
<div class="card-header-content"><h2><span data-icon="book-open"></span> Full Reference</h2></div>
|
|
917
|
+
<span class="card-collapse-icon" data-icon="chevron-down"></span>
|
|
918
|
+
</div>
|
|
919
|
+
<div class="card-body docs-body">
|
|
920
|
+
<p>See the public documentation for live examples and the complete attribute reference:</p>
|
|
921
|
+
<a href="/resources/pro/cta" target="_blank" class="btn btn-ghost btn-sm">
|
|
922
|
+
<span data-icon="external-link"></span> CTA Shortcode Reference
|
|
923
|
+
</a>
|
|
924
|
+
</div>
|
|
925
|
+
</div>
|
|
926
|
+
|
|
927
|
+
</div><!-- /CTA tab -->
|
|
928
|
+
|
|
929
|
+
</div><!-- .tab-content -->
|
|
930
|
+
</div><!-- .tabs -->
|
|
931
|
+
```
|
|
932
|
+
|
|
933
|
+
**Step 3: Commit**
|
|
934
|
+
|
|
935
|
+
```bash
|
|
936
|
+
git add admin/js/views/pro-docs.js admin/js/templates/pro-docs.html
|
|
937
|
+
git commit -m "feat: add Pro Documentation admin view and template"
|
|
938
|
+
```
|
|
939
|
+
|
|
940
|
+
---
|
|
941
|
+
|
|
942
|
+
## Task 7: Wire the view into the admin SPA
|
|
943
|
+
|
|
944
|
+
**Files:**
|
|
945
|
+
- Modify: `admin/js/views/index.js`
|
|
946
|
+
- Modify: `admin/js/app.js`
|
|
947
|
+
- Modify: `admin/js/config/sidebar-config.js`
|
|
948
|
+
|
|
949
|
+
**Step 1: Register the view in index.js**
|
|
950
|
+
|
|
951
|
+
Add to `admin/js/views/index.js`:
|
|
952
|
+
|
|
953
|
+
```js
|
|
954
|
+
import {proDocsView} from './pro-docs.js';
|
|
955
|
+
```
|
|
956
|
+
|
|
957
|
+
Add to the `views` export object:
|
|
958
|
+
```js
|
|
959
|
+
proDocs: proDocsView,
|
|
960
|
+
```
|
|
961
|
+
|
|
962
|
+
**Step 2: Add the route in app.js**
|
|
963
|
+
|
|
964
|
+
In the `coreRoutes` array in `admin/js/app.js`, add after the `actionEditor` route:
|
|
965
|
+
|
|
966
|
+
```js
|
|
967
|
+
{path: '/pro/docs', view: 'proDocs', title: 'Pro Documentation - Domma CMS'},
|
|
968
|
+
```
|
|
969
|
+
|
|
970
|
+
**Step 3: Add the sidebar entry in sidebar-config.js**
|
|
971
|
+
|
|
972
|
+
In `admin/js/config/sidebar-config.js`, add a new "Pro" section after the Documentation section (after the `api-reference` item, before `return items`):
|
|
973
|
+
|
|
974
|
+
```js
|
|
975
|
+
if (canStructure) {
|
|
976
|
+
items.push(
|
|
977
|
+
{divider: true},
|
|
978
|
+
{heading: 'Pro'},
|
|
979
|
+
{
|
|
980
|
+
id: 'pro-docs',
|
|
981
|
+
text: 'Documentation',
|
|
982
|
+
icon: 'zap',
|
|
983
|
+
url: '#/pro/docs',
|
|
984
|
+
section: '#/pro/docs'
|
|
985
|
+
}
|
|
986
|
+
);
|
|
987
|
+
}
|
|
988
|
+
```
|
|
989
|
+
|
|
990
|
+
**Step 4: Verify the route resolves**
|
|
991
|
+
|
|
992
|
+
Navigate to `http://localhost:4096/admin/#/pro/docs` in a browser (or check the server doesn't 404 on it - it's
|
|
993
|
+
client-side routing so the server always returns the admin shell).
|
|
994
|
+
|
|
995
|
+
```bash
|
|
996
|
+
curl -s -o /dev/null -w "%{http_code}" http://localhost:4096/admin/
|
|
997
|
+
```
|
|
998
|
+
Expected: `200`
|
|
999
|
+
|
|
1000
|
+
**Step 5: Commit**
|
|
1001
|
+
|
|
1002
|
+
```bash
|
|
1003
|
+
git add admin/js/views/index.js admin/js/app.js admin/js/config/sidebar-config.js
|
|
1004
|
+
git commit -m "feat: wire Pro Documentation into admin SPA routes and sidebar"
|
|
1005
|
+
```
|
|
1006
|
+
|
|
1007
|
+
---
|
|
1008
|
+
|
|
1009
|
+
## Verification Checklist
|
|
1010
|
+
|
|
1011
|
+
1. `curl http://localhost:4096/resources/pro` → 200, renders hero + 3 cards
|
|
1012
|
+
2. `curl http://localhost:4096/resources/pro/views` → 200, contains aggregation pipeline docs
|
|
1013
|
+
3. `curl http://localhost:4096/resources/pro/actions` → 200, contains step types table
|
|
1014
|
+
4. `curl http://localhost:4096/resources/pro/cta` → 200, contains `[cta]` syntax
|
|
1015
|
+
5. `curl http://localhost:4096/resources` → contains "Pro Features" card text
|
|
1016
|
+
6. Admin at `#/pro/docs` → three tabs render (Views, Actions, CTA Shortcode), icons and syntax highlighting active
|
|
1017
|
+
7. Admin sidebar → "Pro" heading with "Documentation" link visible for admin/manager roles
|