domma-cms 0.44.0 → 0.45.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/CLAUDE.md +53 -53
- package/README.md +27 -27
- package/admin/css/admin.css +1 -1
- package/admin/dist/domma/domma-tools.css +3 -3
- package/admin/dist/domma/domma-tools.min.js +3 -3
- package/admin/index.html +2 -2
- package/admin/js/app.js +1 -1
- package/admin/js/lib/card-builder.js +2 -2
- package/admin/js/lib/crud-tutorial.js +1 -1
- package/admin/js/lib/effect-defs.js +1 -1
- package/admin/js/lib/effects-builder.js +1 -1
- package/admin/js/lib/image-editor.js +1 -1
- package/admin/js/lib/markdown-toolbar.js +2 -2
- package/admin/js/lib/project-context.js +1 -1
- package/admin/js/lib/project-quick-create.js +1 -1
- package/admin/js/lib/scribe-composer.js +1 -1
- package/admin/js/lib/server-restart.js +1 -1
- package/admin/js/lib/shortcode-context-menu.js +2 -2
- package/admin/js/lib/simple-editor.js +1 -1
- package/admin/js/lib/themes.js +1 -1
- package/admin/js/lib/timeline-builder.js +1 -1
- package/admin/js/templates/action-editor.html +8 -8
- package/admin/js/templates/api-endpoint-editor.html +7 -7
- package/admin/js/templates/api-endpoints.html +1 -1
- package/admin/js/templates/api-reference.html +1 -1
- package/admin/js/templates/block-editor.html +6 -6
- package/admin/js/templates/collection-editor.html +1 -1
- package/admin/js/templates/component-editor.html +2 -2
- package/admin/js/templates/dashboard/cache.html +3 -3
- package/admin/js/templates/dashboard/journeys.html +3 -3
- package/admin/js/templates/dashboard/kpi-strip.html +3 -3
- package/admin/js/templates/dashboard/top-pages.html +1 -1
- package/admin/js/templates/dashboard/traffic-chart.html +1 -1
- package/admin/js/templates/docs/api-actions.html +1 -1
- package/admin/js/templates/docs/api-collections.html +4 -4
- package/admin/js/templates/docs/api-pages.html +2 -2
- package/admin/js/templates/docs/api-plugins.html +1 -1
- package/admin/js/templates/docs/api-settings.html +2 -2
- package/admin/js/templates/docs/api-users.html +1 -1
- package/admin/js/templates/docs/components-howto.html +4 -4
- package/admin/js/templates/docs/components-reference.html +21 -21
- package/admin/js/templates/docs/components-rules.html +14 -14
- package/admin/js/templates/docs/components-walkthrough.html +13 -13
- package/admin/js/templates/docs/tutorial-crud.html +49 -49
- package/admin/js/templates/docs/tutorial-forms.html +4 -4
- package/admin/js/templates/docs/tutorial-plugin.html +10 -10
- package/admin/js/templates/docs/usage-actions.html +6 -6
- package/admin/js/templates/docs/usage-cta-shortcode.html +9 -9
- package/admin/js/templates/docs/usage-dconfig.html +4 -4
- package/admin/js/templates/docs/usage-navigation.html +1 -1
- package/admin/js/templates/docs/usage-pages.html +1 -1
- package/admin/js/templates/docs/usage-shortcodes.html +24 -24
- package/admin/js/templates/docs/usage-users-roles.html +3 -3
- package/admin/js/templates/docs/usage-views.html +4 -4
- package/admin/js/templates/documentation.html +1 -1
- package/admin/js/templates/effects.html +752 -752
- package/admin/js/templates/form-editor.html +5 -5
- package/admin/js/templates/forms.html +17 -17
- package/admin/js/templates/login.html +5 -5
- package/admin/js/templates/menu-editor.html +10 -10
- package/admin/js/templates/my-profile.html +17 -17
- package/admin/js/templates/navigation.html +11 -11
- package/admin/js/templates/notifications.html +1 -1
- package/admin/js/templates/page-editor.html +4 -4
- package/admin/js/templates/pro-docs.html +14 -14
- package/admin/js/templates/role-editor.html +70 -70
- package/admin/js/templates/roles.html +10 -10
- package/admin/js/templates/settings.html +10 -10
- package/admin/js/templates/tutorials.html +3 -3
- package/admin/js/templates/view-editor.html +15 -15
- package/admin/js/views/action-editor.js +1 -1
- package/admin/js/views/actions-list.js +1 -1
- package/admin/js/views/api-endpoint-editor.js +2 -2
- package/admin/js/views/api-endpoints.js +2 -2
- package/admin/js/views/api-tokens.js +3 -3
- package/admin/js/views/blocks.js +2 -2
- package/admin/js/views/collection-editor.js +1 -1
- package/admin/js/views/collection-entries.js +1 -1
- package/admin/js/views/collections.js +1 -1
- package/admin/js/views/component-editor.js +1 -1
- package/admin/js/views/components.js +4 -4
- package/admin/js/views/dashboard/widgets/cache.js +1 -1
- package/admin/js/views/dashboard/widgets/journeys.js +1 -1
- package/admin/js/views/dashboard/widgets/kpi-strip.js +1 -1
- package/admin/js/views/form-editor.js +7 -7
- package/admin/js/views/form-submissions.js +1 -1
- package/admin/js/views/forms.js +1 -1
- package/admin/js/views/layouts.js +1 -1
- package/admin/js/views/login.js +2 -2
- package/admin/js/views/menu-editor.js +3 -3
- package/admin/js/views/menu-locations.js +1 -1
- package/admin/js/views/menus.js +3 -3
- package/admin/js/views/navigation.js +8 -8
- package/admin/js/views/page-editor.js +40 -40
- package/admin/js/views/pages.js +3 -3
- package/admin/js/views/plugin-code.js +2 -2
- package/admin/js/views/plugins.js +1 -1
- package/admin/js/views/project-settings.js +1 -1
- package/admin/js/views/projects.js +1 -1
- package/admin/js/views/roles.js +1 -1
- package/admin/js/views/user-editor.js +1 -1
- package/admin/js/views/users.js +3 -3
- package/admin/js/views/view-editor.js +1 -1
- package/admin/js/views/view-preview.js +1 -1
- package/admin/js/views/views-list.js +1 -1
- package/bin/cli.js +8 -8
- package/bin/lib/config-merge.js +44 -44
- package/bin/update.js +16 -16
- package/config/plugins.json +1 -1
- package/package.json +2 -2
- package/plugins/_template/admin/views/index.js +1 -1
- package/plugins/_template/config.js +1 -1
- package/plugins/_template/plugin.js +1 -1
- package/plugins/analytics/admin/templates/analytics.html +3 -3
- package/plugins/analytics/admin/views/analytics.js +1 -1
- package/plugins/analytics/config.js +1 -1
- package/plugins/analytics/plugin.js +4 -4
- package/plugins/analytics/plugin.json +1 -1
- package/plugins/analytics/public/inject-body.html +2 -2
- package/plugins/analytics/public/inject-head.html +1 -1
- package/plugins/blog/admin/templates/blog.html +4 -4
- package/plugins/blog/admin/views/blog.js +3 -3
- package/plugins/blog/admin/views/categories.js +2 -2
- package/plugins/blog/admin/views/comments.js +4 -4
- package/plugins/blog/admin/views/post-editor.js +1 -1
- package/plugins/blog/plugin.js +2 -2
- package/plugins/blog/plugin.json +4 -4
- package/plugins/contacts/admin/views/contacts.js +8 -8
- package/plugins/contacts/plugin.js +4 -4
- package/plugins/contacts/plugin.json +1 -1
- package/plugins/invoice/admin/templates/editor.html +6 -6
- package/plugins/invoice/admin/templates/index.html +4 -4
- package/plugins/invoice/admin/views/editor.js +3 -3
- package/plugins/invoice/admin/views/index.js +4 -4
- package/plugins/invoice/admin/views/issuers.js +1 -1
- package/plugins/invoice/admin/views/party-view.js +3 -3
- package/plugins/invoice/admin/views/receivers.js +1 -1
- package/plugins/invoice/config.js +1 -1
- package/plugins/invoice/plugin.js +1 -1
- package/plugins/invoice/plugin.json +4 -4
- package/plugins/notes/admin/views/notes.js +4 -4
- package/plugins/notes/plugin.js +1 -1
- package/plugins/notes/plugin.json +1 -1
- package/plugins/site-search/admin/templates/site-search.html +3 -3
- package/plugins/site-search/admin/views/site-search.js +1 -1
- package/plugins/site-search/config.js +1 -1
- package/plugins/site-search/plugin.js +4 -4
- package/plugins/site-search/plugin.json +1 -1
- package/plugins/surveys/admin/templates/results.html +1 -1
- package/plugins/surveys/admin/templates/survey-editor.html +4 -4
- package/plugins/surveys/admin/views/audience.js +6 -6
- package/plugins/surveys/admin/views/results.js +3 -3
- package/plugins/surveys/admin/views/survey-editor.js +1 -1
- package/plugins/surveys/admin/views/surveys.js +2 -2
- package/plugins/surveys/plugin.js +1 -1
- package/plugins/surveys/plugin.json +4 -4
- package/plugins/theme-switcher/admin/views/theme-switcher.js +1 -1
- package/plugins/theme-switcher/plugin.json +3 -3
- package/plugins/theme-switcher/public/inject-body.html +28 -28
- package/plugins/theme-switcher/public/inject-head.html +1 -1
- package/plugins/todo/plugin.js +1 -1
- package/public/css/forms.css +1 -1
- package/public/js/collection-browser.js +1 -1
- package/public/js/collection-context.js +1 -1
- package/public/js/form-logic-engine.js +1 -1
- package/public/js/forms.js +2 -1
- package/public/js/site.js +1 -1
- package/scripts/build.js +14 -14
- package/scripts/create-plugin.js +2 -2
- package/scripts/fresh.js +2 -2
- package/scripts/gen-instance-secret.js +1 -1
- package/scripts/pro.js +12 -12
- package/scripts/reset.js +2 -2
- package/scripts/setup.js +15 -15
- package/scripts/users.js +5 -5
- package/scripts/verify-assets.mjs +6 -6
- package/server/config.js +1 -1
- package/server/middleware/auth.js +253 -253
- package/server/middleware/managerAuth.js +3 -3
- package/server/routes/api/actions.js +4 -4
- package/server/routes/api/api-endpoints.js +7 -7
- package/server/routes/api/api-tokens.js +5 -5
- package/server/routes/api/auth.js +309 -309
- package/server/routes/api/blocks.js +3 -3
- package/server/routes/api/collections.js +18 -18
- package/server/routes/api/dashboard.js +5 -5
- package/server/routes/api/effects.js +2 -2
- package/server/routes/api/endpoints-public.js +5 -5
- package/server/routes/api/forms.js +47 -47
- package/server/routes/api/menu-locations.js +3 -3
- package/server/routes/api/menus.js +7 -7
- package/server/routes/api/navigation.js +42 -42
- package/server/routes/api/notifications.js +2 -2
- package/server/routes/api/pages.js +14 -2
- package/server/routes/api/plugin-marketplace.js +3 -3
- package/server/routes/api/plugins.js +6 -6
- package/server/routes/api/projects.js +9 -9
- package/server/routes/api/scaffold.js +7 -7
- package/server/routes/api/settings.js +6 -6
- package/server/routes/api/sidebar.js +1 -1
- package/server/routes/api/users.js +5 -5
- package/server/routes/api/versions.js +1 -1
- package/server/routes/api/views.js +1 -1
- package/server/routes/docs-public.js +3 -3
- package/server/routes/public.js +14 -14
- package/server/server.js +34 -16
- package/server/services/actions.js +19 -19
- package/server/services/adapters/FileAdapter.js +2 -2
- package/server/services/adapters/MongoAdapter.js +5 -5
- package/server/services/apiEndpoints.js +15 -15
- package/server/services/apiTokens.js +7 -7
- package/server/services/blocks.js +13 -13
- package/server/services/cache/drivers/MemoryDriver.js +3 -3
- package/server/services/cache/drivers/NoneDriver.js +1 -1
- package/server/services/cache/index.js +5 -5
- package/server/services/collections.js +14 -14
- package/server/services/components.js +9 -9
- package/server/services/connectionManager.js +4 -4
- package/server/services/content.js +25 -2
- package/server/services/docs.js +14 -14
- package/server/services/email.js +167 -167
- package/server/services/filterEngine.js +6 -6
- package/server/services/forms.js +18 -10
- package/server/services/health.js +1 -1
- package/server/services/hooks.js +7 -7
- package/server/services/images.js +4 -4
- package/server/services/managerClient.js +1 -1
- package/server/services/markdown.js +79 -79
- package/server/services/menuRender.js +5 -5
- package/server/services/menus-migration.js +3 -3
- package/server/services/menus.js +31 -31
- package/server/services/permissionRegistry.js +1 -1
- package/server/services/pluginFiles.js +5 -5
- package/server/services/pluginInstaller.js +17 -17
- package/server/services/pluginScaffold.js +1 -1
- package/server/services/plugins.js +17 -17
- package/server/services/presetCollections.js +2 -2
- package/server/services/projects.js +35 -26
- package/server/services/recipes/contact-list.json +1 -1
- package/server/services/recipes/onboarding.json +8 -8
- package/server/services/references.js +8 -8
- package/server/services/renderer.js +9 -9
- package/server/services/roles.js +9 -9
- package/server/services/rowAccess.js +10 -10
- package/server/services/scaffolder.js +30 -30
- package/server/services/sidebar-migration.js +10 -10
- package/server/services/sitemap.js +1 -1
- package/server/services/userProfiles.js +199 -199
- package/server/services/userRoles.js +7 -7
- package/server/services/users.js +302 -302
- package/server/services/versions.js +3 -3
- package/server/services/viewPipeline.js +6 -6
- package/server/services/views.js +11 -11
- package/server/templates/page.html +5 -5
|
@@ -39,14 +39,14 @@
|
|
|
39
39
|
<div>
|
|
40
40
|
<label class="form-label">Target Collection <span style="color:var(--dm-danger,#f87171);">*</span></label>
|
|
41
41
|
<select id="action-collection" class="form-input">
|
|
42
|
-
<option value=""
|
|
42
|
+
<option value="">- select collection -</option>
|
|
43
43
|
</select>
|
|
44
44
|
<small class="text-muted">The collection this action operates on.</small>
|
|
45
45
|
</div>
|
|
46
46
|
<div>
|
|
47
47
|
<label class="form-label">Project</label>
|
|
48
48
|
<select id="action-project" class="form-input">
|
|
49
|
-
<option value=""
|
|
49
|
+
<option value="">- none -</option>
|
|
50
50
|
</select>
|
|
51
51
|
<small class="text-muted">Tag this action to a project for grouping.</small>
|
|
52
52
|
</div>
|
|
@@ -117,10 +117,10 @@
|
|
|
117
117
|
<div class="card">
|
|
118
118
|
<div class="card-body" style="font-size:.8rem;color:var(--dm-text-muted,#888);">
|
|
119
119
|
<strong>Template variables:</strong>
|
|
120
|
-
<code>{{entry.data.fieldName}}</code>
|
|
121
|
-
<code>{{now}}</code>
|
|
122
|
-
<code>{{user.name}}</code>
|
|
123
|
-
<code>{{env.CMS_PUBLIC_*}}</code>
|
|
120
|
+
<code>{{entry.data.fieldName}}</code> - entry field value |
|
|
121
|
+
<code>{{now}}</code> - current ISO timestamp |
|
|
122
|
+
<code>{{user.name}}</code> - executing user's name |
|
|
123
|
+
<code>{{env.CMS_PUBLIC_*}}</code> - public environment variables
|
|
124
124
|
</div>
|
|
125
125
|
</div>
|
|
126
126
|
</div>
|
|
@@ -153,8 +153,8 @@
|
|
|
153
153
|
<div>
|
|
154
154
|
<label class="form-label">Mode</label>
|
|
155
155
|
<select id="action-rowlevel-mode" class="form-input">
|
|
156
|
-
<option value="owner">Owner
|
|
157
|
-
<option value="field">Field Match
|
|
156
|
+
<option value="owner">Owner - entry was created by the current user</option>
|
|
157
|
+
<option value="field">Field Match - a field on the entry matches the user</option>
|
|
158
158
|
</select>
|
|
159
159
|
</div>
|
|
160
160
|
<div id="action-rowlevel-field-group" style="display:none;">
|
|
@@ -44,14 +44,14 @@
|
|
|
44
44
|
<div class="form-group">
|
|
45
45
|
<label class="form-label" for="ep-mode">Mode</label>
|
|
46
46
|
<select class="form-input" id="ep-mode">
|
|
47
|
-
<option value="list">List
|
|
48
|
-
<option value="single">Single
|
|
47
|
+
<option value="list">List - array of entries</option>
|
|
48
|
+
<option value="single">Single - first match or 404</option>
|
|
49
49
|
</select>
|
|
50
50
|
</div>
|
|
51
51
|
</div>
|
|
52
52
|
<label style="display:flex;align-items:center;gap:.5rem;cursor:pointer;margin-top:.5rem;padding-top:.75rem;border-top:1px solid rgba(127,127,127,.18);">
|
|
53
53
|
<input type="checkbox" id="ep-enabled" checked> <strong>Enabled</strong>
|
|
54
|
-
<span class="text-muted" style="font-size:.85rem;"
|
|
54
|
+
<span class="text-muted" style="font-size:.85rem;">- disabled endpoints return 404</span>
|
|
55
55
|
</label>
|
|
56
56
|
</div>
|
|
57
57
|
</div>
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
</div>
|
|
66
66
|
<div class="card-body">
|
|
67
67
|
<div id="ep-filter-rows"></div>
|
|
68
|
-
<p class="text-muted" style="font-size:.8rem;margin:.5rem 0 0;">Values may use <code>{{params.name}}</code> (from a <code>:name</code> path segment, required) or <code>{{query.name}}</code> (optional
|
|
68
|
+
<p class="text-muted" style="font-size:.8rem;margin:.5rem 0 0;">Values may use <code>{{params.name}}</code> (from a <code>:name</code> path segment, required) or <code>{{query.name}}</code> (optional - the filter is skipped when absent).</p>
|
|
69
69
|
<div style="display:grid;grid-template-columns:2fr 1fr 1fr;gap:.75rem;margin-top:1rem;">
|
|
70
70
|
<div class="form-group">
|
|
71
71
|
<label class="form-label" for="ep-sort">Sort field</label>
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
<div class="card">
|
|
93
93
|
<div class="card-header"><h2>Response fields</h2></div>
|
|
94
94
|
<div class="card-body">
|
|
95
|
-
<p class="text-muted" style="font-size:.85rem;margin:0 0 .5rem;">Tick fields to return only those
|
|
95
|
+
<p class="text-muted" style="font-size:.85rem;margin:0 0 .5rem;">Tick fields to return only those - none ticked returns everything.</p>
|
|
96
96
|
<div id="ep-fields-list" style="display:flex;flex-wrap:wrap;gap:.5rem 1.25rem;"></div>
|
|
97
97
|
</div>
|
|
98
98
|
</div>
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
<div class="form-group">
|
|
120
120
|
<label class="form-label" for="tryit-query">Extra query string (optional)</label>
|
|
121
121
|
<input type="text" class="form-input" id="tryit-query" placeholder="nation=France&status=published">
|
|
122
|
-
<p class="text-muted" style="font-size:.8rem;margin:.25rem 0 0;">Applied as extra filters <em>on top of</em> the definition's own filters (which always win). Only fields this endpoint returns can be filtered; operators work too
|
|
122
|
+
<p class="text-muted" style="font-size:.8rem;margin:.25rem 0 0;">Applied as extra filters <em>on top of</em> the definition's own filters (which always win). Only fields this endpoint returns can be filtered; operators work too - e.g. <code>title_contains=cup</code>. <code>page</code>, <code>limit</code>, <code>sort</code> and <code>order</code> control pagination/sort instead (<code>limit</code> is capped at the endpoint's own limit); <code>search</code> is reserved.</p>
|
|
123
123
|
</div>
|
|
124
124
|
<button class="btn btn-primary" id="tryit-send" style="width:100%;"><span data-icon="play"></span> Send</button>
|
|
125
125
|
<div id="tryit-result" style="display:none;margin-top:.75rem;">
|
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
|
|
132
132
|
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:.4rem;">
|
|
133
133
|
<span class="form-label" style="margin:0;">Response</span>
|
|
134
|
-
<span id="tryit-status" class="badge badge-secondary"
|
|
134
|
+
<span id="tryit-status" class="badge badge-secondary">-</span>
|
|
135
135
|
</div>
|
|
136
136
|
<div id="tryit-headers-group">
|
|
137
137
|
<p class="text-muted" style="font-size:.78rem;margin:0 0 .2rem;text-transform:uppercase;letter-spacing:.03em;">Headers</p>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<a class="btn btn-primary" href="#/api-endpoints/new"><span data-icon="plus"></span> New endpoint</a>
|
|
5
5
|
</div>
|
|
6
6
|
</div>
|
|
7
|
-
<p class="text-muted mb-4">Custom REST endpoints over collection data, served at <code>/api/x/<project><path></code>. Each endpoint binds a clean URL to a fixed collection query
|
|
7
|
+
<p class="text-muted mb-4">Custom REST endpoints over collection data, served at <code>/api/x/<project><path></code>. Each endpoint binds a clean URL to a fixed collection query - definitions are data, never code.</p>
|
|
8
8
|
|
|
9
9
|
<div class="card">
|
|
10
10
|
<div class="card-body">
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
</div>
|
|
19
19
|
|
|
20
20
|
<p class="lead">
|
|
21
|
-
Pick an area below
|
|
21
|
+
Pick an area below - each opens as its own page, and every area is listed under
|
|
22
22
|
<strong>Documentation → API Reference</strong> in the sidebar.
|
|
23
23
|
</p>
|
|
24
24
|
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
<div class="mt-3">
|
|
29
29
|
<label class="form-label">Project</label>
|
|
30
30
|
<select id="block-project" class="form-input">
|
|
31
|
-
<option value=""
|
|
31
|
+
<option value="">- none -</option>
|
|
32
32
|
</select>
|
|
33
33
|
<small class="text-muted">Tag this block to a project for grouping.</small>
|
|
34
34
|
</div>
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
</div>
|
|
92
92
|
</div>
|
|
93
93
|
|
|
94
|
-
<!-- Editor body
|
|
94
|
+
<!-- Editor body - split pane -->
|
|
95
95
|
<div id="block-editor-body" class="editor-body editor-mode-split" style="min-height:460px;">
|
|
96
96
|
|
|
97
97
|
<!-- Write pane -->
|
|
@@ -106,7 +106,7 @@
|
|
|
106
106
|
|
|
107
107
|
<!-- Preview pane -->
|
|
108
108
|
<div class="editor-pane editor-pane--preview" style="flex-direction:column;overflow:hidden;">
|
|
109
|
-
<!-- Sample data inputs
|
|
109
|
+
<!-- Sample data inputs - auto-populated by JS -->
|
|
110
110
|
<div id="block-sample-data" style="
|
|
111
111
|
border-bottom:1px solid var(--dm-border,rgba(255,255,255,.08));
|
|
112
112
|
padding:.6rem .75rem;
|
|
@@ -139,7 +139,7 @@
|
|
|
139
139
|
<code class="dm-code-inline" style="font-size:.9em;">@keyframes</code>,
|
|
140
140
|
<code class="dm-code-inline" style="font-size:.9em;">@font-face</code>, and
|
|
141
141
|
<code class="dm-code-inline" style="font-size:.9em;">@import</code>
|
|
142
|
-
cannot be scoped
|
|
142
|
+
cannot be scoped - use site-wide Custom CSS in Settings for those.
|
|
143
143
|
</p>
|
|
144
144
|
<textarea id="block-css"
|
|
145
145
|
class="editor-textarea"
|
|
@@ -171,7 +171,7 @@ h2 { font-size: 1.5rem; }
|
|
|
171
171
|
<tbody>
|
|
172
172
|
<tr>
|
|
173
173
|
<td><code class="dm-code-inline">{{fieldName}}</code></td>
|
|
174
|
-
<td>Any entry field
|
|
174
|
+
<td>Any entry field - e.g. <code class="dm-code-inline">{{title}}</code>, <code class="dm-code-inline">{{rating}}</code>,
|
|
175
175
|
<code class="dm-code-inline">{{message}}</code></td>
|
|
176
176
|
</tr>
|
|
177
177
|
<tr>
|
|
@@ -209,7 +209,7 @@ h2 { font-size: 1.5rem; }
|
|
|
209
209
|
<code class="dm-code-inline">mm</code> <code class="dm-code-inline">m</code>
|
|
210
210
|
<code class="dm-code-inline">ss</code> <code class="dm-code-inline">s</code>
|
|
211
211
|
<code class="dm-code-inline">A</code> <code class="dm-code-inline">a</code>
|
|
212
|
-
|
|
212
|
+
- any literal character that isn't one of these tokens passes through unchanged
|
|
213
213
|
(so <code class="dm-code-inline">DD/MM/YYYY</code>, <code class="dm-code-inline">HH:mm</code>,
|
|
214
214
|
and <code class="dm-code-inline">dddd D MMMM YYYY</code> all work).
|
|
215
215
|
</p>
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
<div class="col-6">
|
|
58
58
|
<label class="form-label">Project</label>
|
|
59
59
|
<select id="collection-project" class="form-input">
|
|
60
|
-
<option value=""
|
|
60
|
+
<option value="">- none -</option>
|
|
61
61
|
</select>
|
|
62
62
|
<p class="form-hint text-muted" style="margin-top:.3rem;font-size:.8rem;">Tag this collection to a project for grouping.</p>
|
|
63
63
|
</div>
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
<div class="mt-3">
|
|
32
32
|
<label class="form-label">Project</label>
|
|
33
33
|
<select id="component-project" class="form-input">
|
|
34
|
-
<option value=""
|
|
34
|
+
<option value="">- none -</option>
|
|
35
35
|
</select>
|
|
36
36
|
<small class="text-muted">Tag this component to a project for grouping.</small>
|
|
37
37
|
</div>
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
</div>
|
|
44
44
|
</div>
|
|
45
45
|
|
|
46
|
-
<!-- Editor body
|
|
46
|
+
<!-- Editor body - tabs on the left, preview on the right -->
|
|
47
47
|
<div class="card card-collapsible editor-card mb-3">
|
|
48
48
|
<div class="card-header">
|
|
49
49
|
<h2>Source</h2>
|
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
<div class="dash-cache-grid">
|
|
9
9
|
<div class="dash-cache-stat">
|
|
10
10
|
<div class="dash-cache-stat-label">Hit rate</div>
|
|
11
|
-
<div class="dash-cache-stat-value" data-field="hit-rate"
|
|
11
|
+
<div class="dash-cache-stat-value" data-field="hit-rate">-</div>
|
|
12
12
|
<div class="dash-cache-stat-sub" data-field="hits-misses">no traffic yet</div>
|
|
13
13
|
</div>
|
|
14
14
|
<div class="dash-cache-stat">
|
|
15
15
|
<div class="dash-cache-stat-label">Entries</div>
|
|
16
|
-
<div class="dash-cache-stat-value" data-field="size"
|
|
16
|
+
<div class="dash-cache-stat-value" data-field="size">-</div>
|
|
17
17
|
<div class="dash-cache-stat-sub" data-field="size-bar"><span data-field="size-fill"></span></div>
|
|
18
18
|
</div>
|
|
19
19
|
<div class="dash-cache-stat">
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
<div class="dash-cache-stat">
|
|
25
25
|
<div class="dash-cache-stat-label">Last cleared</div>
|
|
26
26
|
<div class="dash-cache-stat-value" data-field="last-cleared">never</div>
|
|
27
|
-
<div class="dash-cache-stat-sub" data-field="driver">driver:
|
|
27
|
+
<div class="dash-cache-stat-sub" data-field="driver">driver: -</div>
|
|
28
28
|
</div>
|
|
29
29
|
</div>
|
|
30
30
|
<div class="dash-cache-actions">
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<h3>User journeys
|
|
1
|
+
<h3>User journeys - last 7 days</h3>
|
|
2
2
|
<div class="dash-journey-grid">
|
|
3
3
|
<div>
|
|
4
4
|
<h4>Top entry pages</h4>
|
|
@@ -13,5 +13,5 @@
|
|
|
13
13
|
<div data-field="paths"></div>
|
|
14
14
|
</div>
|
|
15
15
|
</div>
|
|
16
|
-
<p class="dash-bounce">Bounce rate: <strong data-field="bounce"
|
|
17
|
-
<p class="dash-empty" hidden>No journey data yet
|
|
16
|
+
<p class="dash-bounce">Bounce rate: <strong data-field="bounce">-</strong></p>
|
|
17
|
+
<p class="dash-empty" hidden>No journey data yet - encourage some traffic and check back.</p>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<div class="dash-card dash-kpi">
|
|
2
2
|
<span class="dash-kpi-icon" data-icon="trending-up"></span>
|
|
3
3
|
<div>
|
|
4
|
-
<div class="dash-kpi-value" data-field="hits-today"
|
|
4
|
+
<div class="dash-kpi-value" data-field="hits-today">-</div>
|
|
5
5
|
<div class="dash-kpi-label">Hits today</div>
|
|
6
6
|
<div class="dash-kpi-delta" data-field="hits-delta"></div>
|
|
7
7
|
</div>
|
|
@@ -9,14 +9,14 @@
|
|
|
9
9
|
<div class="dash-card dash-kpi">
|
|
10
10
|
<span class="dash-kpi-icon" data-icon="users"></span>
|
|
11
11
|
<div>
|
|
12
|
-
<div class="dash-kpi-value" data-field="active-sessions"
|
|
12
|
+
<div class="dash-kpi-value" data-field="active-sessions">-</div>
|
|
13
13
|
<div class="dash-kpi-label">Active sessions (5m)</div>
|
|
14
14
|
</div>
|
|
15
15
|
</div>
|
|
16
16
|
<div class="dash-card dash-kpi">
|
|
17
17
|
<span class="dash-kpi-icon" data-icon="inbox"></span>
|
|
18
18
|
<div>
|
|
19
|
-
<div class="dash-kpi-value" data-field="submissions-week"
|
|
19
|
+
<div class="dash-kpi-value" data-field="submissions-week">-</div>
|
|
20
20
|
<div class="dash-kpi-label">Submissions this week</div>
|
|
21
21
|
</div>
|
|
22
22
|
</div>
|
|
@@ -138,7 +138,7 @@
|
|
|
138
138
|
<h3><span class="method-badge method-post">POST</span><span class="endpoint-path">/api/actions/:slug/public</span>
|
|
139
139
|
</h3>
|
|
140
140
|
<p class="auth-note">Requires: JWT + role in <code>access.roles</code></p>
|
|
141
|
-
<p>Execute an action publicly. Always requires a valid JWT
|
|
141
|
+
<p>Execute an action publicly. Always requires a valid JWT - the role is checked against <code>access.roles</code>.
|
|
142
142
|
Request body and response shape are identical to the admin <code>/execute</code> endpoint.</p>
|
|
143
143
|
|
|
144
144
|
</div>
|
|
@@ -156,7 +156,7 @@
|
|
|
156
156
|
</tr>
|
|
157
157
|
</tbody>
|
|
158
158
|
</table>
|
|
159
|
-
<pre class="code-block"><code>// Response 201
|
|
159
|
+
<pre class="code-block"><code>// Response 201 - returns the created schema object
|
|
160
160
|
|
|
161
161
|
// Error 409
|
|
162
162
|
{ "error": "A collection with that slug already exists" }</code></pre>
|
|
@@ -219,7 +219,7 @@
|
|
|
219
219
|
</tr>
|
|
220
220
|
<tr>
|
|
221
221
|
<td><code>search</code></td>
|
|
222
|
-
<td
|
|
222
|
+
<td>-</td>
|
|
223
223
|
<td>Full-text search query</td>
|
|
224
224
|
</tr>
|
|
225
225
|
</tbody>
|
|
@@ -236,7 +236,7 @@
|
|
|
236
236
|
</h3>
|
|
237
237
|
<p class="auth-note">Requires Bearer token + <code>collections</code> permission.</p>
|
|
238
238
|
<p>Create a new entry. Data is validated against the collection schema.</p>
|
|
239
|
-
<pre class="code-block"><code>// Response 201
|
|
239
|
+
<pre class="code-block"><code>// Response 201 - returns the created entry</code></pre>
|
|
240
240
|
|
|
241
241
|
<h3><span class="method-badge method-put">PUT</span><span class="endpoint-path">/api/collections/:slug/entries/:id</span>
|
|
242
242
|
</h3>
|
|
@@ -280,7 +280,7 @@
|
|
|
280
280
|
</tr>
|
|
281
281
|
</tbody>
|
|
282
282
|
</table>
|
|
283
|
-
<pre class="code-block"><code>// Response 200
|
|
283
|
+
<pre class="code-block"><code>// Response 200 - file download
|
|
284
284
|
// Content-Disposition: attachment; filename="blog-entries.json"</code></pre>
|
|
285
285
|
|
|
286
286
|
<h3><span class="method-badge method-post">POST</span><span class="endpoint-path">/api/collections/:slug/import</span>
|
|
@@ -159,7 +159,7 @@
|
|
|
159
159
|
</tr>
|
|
160
160
|
</tbody>
|
|
161
161
|
</table>
|
|
162
|
-
<pre class="code-block"><code>// Response 201
|
|
162
|
+
<pre class="code-block"><code>// Response 201 - returns the created page object</code></pre>
|
|
163
163
|
|
|
164
164
|
<h3><span class="method-badge method-put">PUT</span><span class="endpoint-path">/api/pages/*</span>
|
|
165
165
|
</h3>
|
|
@@ -191,7 +191,7 @@
|
|
|
191
191
|
</tr>
|
|
192
192
|
</tbody>
|
|
193
193
|
</table>
|
|
194
|
-
<pre class="code-block"><code>// Response 200
|
|
194
|
+
<pre class="code-block"><code>// Response 200 - returns the updated page object
|
|
195
195
|
|
|
196
196
|
// Error 404
|
|
197
197
|
{ "error": "Page not found" }
|
|
@@ -122,7 +122,7 @@
|
|
|
122
122
|
<h3><span class="method-badge method-get">GET</span><span class="endpoint-path">/api/plugins/admin-config</span>
|
|
123
123
|
</h3>
|
|
124
124
|
<p class="auth-note">Requires Bearer token (any role).</p>
|
|
125
|
-
<p>Return the merged admin configuration for all enabled plugins
|
|
125
|
+
<p>Return the merged admin configuration for all enabled plugins - sidebar items, SPA routes, and view
|
|
126
126
|
entry points.</p>
|
|
127
127
|
<pre class="code-block"><code>// Response 200
|
|
128
128
|
{
|
|
@@ -79,9 +79,9 @@
|
|
|
79
79
|
<h3><span class="method-badge method-put">PUT</span><span class="endpoint-path">/api/settings</span>
|
|
80
80
|
</h3>
|
|
81
81
|
<p class="auth-note">Requires Bearer token + <code>settings</code> permission.</p>
|
|
82
|
-
<p>Replace the site settings object. Send the full merged object
|
|
82
|
+
<p>Replace the site settings object. Send the full merged object - partial updates overwrite the
|
|
83
83
|
entire config.</p>
|
|
84
|
-
<pre class="code-block"><code>// Request body
|
|
84
|
+
<pre class="code-block"><code>// Request body - full site settings object
|
|
85
85
|
{ "siteName": "My Site", "adminTheme": "ocean-dark", ... }
|
|
86
86
|
|
|
87
87
|
// Response 200
|
|
@@ -172,7 +172,7 @@
|
|
|
172
172
|
</tr>
|
|
173
173
|
</tbody>
|
|
174
174
|
</table>
|
|
175
|
-
<pre class="code-block"><code>// Response 200
|
|
175
|
+
<pre class="code-block"><code>// Response 200 - returns the updated user object</code></pre>
|
|
176
176
|
|
|
177
177
|
<h3><span class="method-badge method-delete">DELETE</span><span
|
|
178
178
|
class="endpoint-path">/api/users/:id</span></h3>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<div class="view-header">
|
|
2
|
-
<h1><span data-icon="component"></span> Components
|
|
2
|
+
<h1><span data-icon="component"></span> Components - How-To</h1>
|
|
3
3
|
<a href="#/components/new" class="btn btn-primary btn-sm"><span data-icon="plus"></span> New Component</a>
|
|
4
4
|
</div>
|
|
5
5
|
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
becomes the tag <code><dm-price-tag></code>.</li>
|
|
29
29
|
<li>Fill the <code><template></code>, <code><props></code> and <code><script></code>
|
|
30
30
|
tabs (the editor watches the live preview as you type).</li>
|
|
31
|
-
<li><strong>Save</strong>. It compiles first
|
|
31
|
+
<li><strong>Save</strong>. It compiles first - fix any reported errors and it lands on disk.</li>
|
|
32
32
|
</ol>
|
|
33
33
|
|
|
34
34
|
<hr>
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
|
|
50
50
|
<h2>Add state and respond to a click</h2>
|
|
51
51
|
<p>Render the markup with <code>data-action</code> hooks, then attach <strong>one</strong> delegated
|
|
52
|
-
listener to the shadow root in <code>onMount</code>. Mutate state with <code>this.set()</code>
|
|
52
|
+
listener to the shadow root in <code>onMount</code>. Mutate state with <code>this.set()</code> - the
|
|
53
53
|
template re-renders automatically.</p>
|
|
54
54
|
<pre class="code-block"><code><template>
|
|
55
55
|
<div class="dm-counter">
|
|
@@ -153,7 +153,7 @@ onMount() { this.set({ count: this.props.initial }); }</code></pre>
|
|
|
153
153
|
<h2>Move a component between sites</h2>
|
|
154
154
|
<ol>
|
|
155
155
|
<li>On <a href="#/components">Components</a>, click <span data-icon="download"></span> Export on the
|
|
156
|
-
row
|
|
156
|
+
row - you'll download <code>name.dmcomponent.json</code>.</li>
|
|
157
157
|
<li>On the other site, click <strong>Import</strong> and pick that file. On a name clash you'll be
|
|
158
158
|
asked to confirm an overwrite.</li>
|
|
159
159
|
</ol>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<div class="view-header">
|
|
2
|
-
<h1><span data-icon="component"></span> Components
|
|
2
|
+
<h1><span data-icon="component"></span> Components - Reference</h1>
|
|
3
3
|
<a href="#/components" class="btn btn-ghost btn-sm"><span data-icon="component"></span> Manage Components</a>
|
|
4
4
|
</div>
|
|
5
5
|
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
|
|
18
18
|
<p class="lead">
|
|
19
19
|
Components are small, reusable custom elements you author in one file and drop into any page.
|
|
20
|
-
Each one is a single <code>.dmc</code> file with up to four sections
|
|
21
|
-
<code><props></code>, <code><script></code> and <code><style></code>
|
|
20
|
+
Each one is a single <code>.dmc</code> file with up to four sections - <code><template></code>,
|
|
21
|
+
<code><props></code>, <code><script></code> and <code><style></code> - and the CMS
|
|
22
22
|
compiles it to a self-contained browser module that registers a
|
|
23
23
|
<code><dm-<em>name</em>></code> custom element. No build step, no framework wiring.
|
|
24
24
|
</p>
|
|
@@ -55,13 +55,13 @@ export default {};
|
|
|
55
55
|
.dm-greeting { font-weight: 600; }
|
|
56
56
|
</style></code></pre>
|
|
57
57
|
|
|
58
|
-
<p>Saving compiles the source <em>before</em> it is written to disk
|
|
58
|
+
<p>Saving compiles the source <em>before</em> it is written to disk - a malformed component never
|
|
59
59
|
reaches the filesystem. The compiler reports precise, per-block errors (see
|
|
60
60
|
<a href="#/docs/components-rules">Rules</a> for every error code).</p>
|
|
61
61
|
|
|
62
62
|
<hr>
|
|
63
63
|
|
|
64
|
-
<h2><code><template></code>
|
|
64
|
+
<h2><code><template></code> - markup</h2>
|
|
65
65
|
|
|
66
66
|
<p>Plain HTML plus a Handlebars-style expression syntax. Data comes from the component's
|
|
67
67
|
<code>props</code> and reactive <code>data()</code> state. Supported syntax:</p>
|
|
@@ -92,7 +92,7 @@ export default {};
|
|
|
92
92
|
|
|
93
93
|
<hr>
|
|
94
94
|
|
|
95
|
-
<h2><code><props></code>
|
|
95
|
+
<h2><code><props></code> - typed inputs</h2>
|
|
96
96
|
|
|
97
97
|
<p>A JSON <strong>object</strong> (not an array). Each key is a prop name; each value declares a
|
|
98
98
|
<code>type</code> and may add a <code>default</code> and a <code>label</code> (shown in the editor's
|
|
@@ -110,17 +110,17 @@ export default {};
|
|
|
110
110
|
|
|
111
111
|
<p>Props are passed as HTML attributes where the value is always a string; the runtime coerces it to
|
|
112
112
|
the declared type (so <code>step="2"</code> arrives as the number <code>2</code>). Read props inside
|
|
113
|
-
<code>onMount()</code> and methods via <code>this.props</code>
|
|
113
|
+
<code>onMount()</code> and methods via <code>this.props</code> - see the script API below.</p>
|
|
114
114
|
|
|
115
115
|
<hr>
|
|
116
116
|
|
|
117
|
-
<h2><code><script></code>
|
|
117
|
+
<h2><code><script></code> - behaviour</h2>
|
|
118
118
|
|
|
119
119
|
<p>An ES module with a single <code>export default { … }</code> object describing the component. The
|
|
120
120
|
export is the only requirement; every key inside it is optional.</p>
|
|
121
121
|
|
|
122
122
|
<pre class="code-block"><code>export default {
|
|
123
|
-
// Reactive state. Called WITHOUT `this`
|
|
123
|
+
// Reactive state. Called WITHOUT `this` - do not read props here.
|
|
124
124
|
data() { return { count: 0 }; },
|
|
125
125
|
|
|
126
126
|
// Methods are bound to the component context (`this`).
|
|
@@ -128,7 +128,7 @@ export default {};
|
|
|
128
128
|
inc() { this.set({ count: this.data.count + this.props.step }); }
|
|
129
129
|
},
|
|
130
130
|
|
|
131
|
-
// Lifecycle
|
|
131
|
+
// Lifecycle - bound to `this`; props and the element are available here.
|
|
132
132
|
onMount() { this.set({ count: this.props.initial }); },
|
|
133
133
|
onUnmount() { /* clean up timers, listeners, etc. */ }
|
|
134
134
|
};</code></pre>
|
|
@@ -138,10 +138,10 @@ export default {};
|
|
|
138
138
|
<tr><th>Key</th><th>What it is</th></tr>
|
|
139
139
|
</thead>
|
|
140
140
|
<tbody>
|
|
141
|
-
<tr><td><code>data()</code></td><td>Returns the initial reactive state object. Called with no <code>this</code> binding
|
|
141
|
+
<tr><td><code>data()</code></td><td>Returns the initial reactive state object. Called with no <code>this</code> binding - <strong>props are not available here</strong>; initialise from props in <code>onMount()</code>.</td></tr>
|
|
142
142
|
<tr><td><code>methods</code></td><td>Object of functions bound to the component context.</td></tr>
|
|
143
143
|
<tr><td><code>onMount()</code></td><td>Lifecycle hook fired when the element is attached to the DOM. Props and the element node are available.</td></tr>
|
|
144
|
-
<tr><td><code>onUnmount()</code></td><td>Lifecycle hook fired when the element is removed
|
|
144
|
+
<tr><td><code>onUnmount()</code></td><td>Lifecycle hook fired when the element is removed - clear intervals/listeners here.</td></tr>
|
|
145
145
|
</tbody>
|
|
146
146
|
</table>
|
|
147
147
|
|
|
@@ -155,7 +155,7 @@ export default {};
|
|
|
155
155
|
<tr><td><code>this.props</code></td><td>The (type-coerced) props the element was used with.</td></tr>
|
|
156
156
|
<tr><td><code>this.data</code></td><td>The current reactive state snapshot.</td></tr>
|
|
157
157
|
<tr><td><code>this.set({ … })</code></td><td>Patch reactive state; the template re-renders with the new values.</td></tr>
|
|
158
|
-
<tr><td><code>this.el</code></td><td>The custom-element DOM node. Its rendered markup lives in <code>this.el.shadowRoot</code>
|
|
158
|
+
<tr><td><code>this.el</code></td><td>The custom-element DOM node. Its rendered markup lives in <code>this.el.shadowRoot</code> - attach event listeners there.</td></tr>
|
|
159
159
|
</tbody>
|
|
160
160
|
</table>
|
|
161
161
|
|
|
@@ -165,7 +165,7 @@ export default {};
|
|
|
165
165
|
|
|
166
166
|
<hr>
|
|
167
167
|
|
|
168
|
-
<h2><code><style></code>
|
|
168
|
+
<h2><code><style></code> - scoped CSS</h2>
|
|
169
169
|
|
|
170
170
|
<p>Optional. CSS here is scoped to the component's shadow DOM, so selectors can't leak out and the
|
|
171
171
|
page's styles can't leak in. By convention components prefix their root class with
|
|
@@ -231,7 +231,7 @@ export default {};
|
|
|
231
231
|
|
|
232
232
|
<h3>Bundled & plugin components</h3>
|
|
233
233
|
<p>The <code>bundled</code> flag marks a component as part of fresh-install seed data. Plugins may
|
|
234
|
-
also contribute components via the <code>registerComponent()</code> hook
|
|
234
|
+
also contribute components via the <code>registerComponent()</code> hook - these appear in the list
|
|
235
235
|
with a <span class="badge badge-secondary">plugin</span> badge, are served from memory, and are
|
|
236
236
|
<strong>read-only</strong> from the admin (you can't edit or delete them, and you can't save a
|
|
237
237
|
component whose name a plugin already owns).</p>
|
|
@@ -239,14 +239,14 @@ export default {};
|
|
|
239
239
|
<hr>
|
|
240
240
|
|
|
241
241
|
<h2>The five seeded starter components</h2>
|
|
242
|
-
<p>Fresh installs ship with these (never overwritten if you've edited them)
|
|
242
|
+
<p>Fresh installs ship with these (never overwritten if you've edited them) - open any in
|
|
243
243
|
<a href="#/components">Components</a> to read the full source:</p>
|
|
244
244
|
<ul>
|
|
245
|
-
<li><code>counter</code>
|
|
246
|
-
<li><code>copy-button</code>
|
|
247
|
-
<li><code>reveal-panel</code>
|
|
248
|
-
<li><code>testimonial-card</code>
|
|
249
|
-
<li><code>countdown-timer</code>
|
|
245
|
+
<li><code>counter</code> - state, methods and lifecycle in one small example</li>
|
|
246
|
+
<li><code>copy-button</code> - an async method using the clipboard API</li>
|
|
247
|
+
<li><code>reveal-panel</code> - conditional rendering plus a <code><slot></code></li>
|
|
248
|
+
<li><code>testimonial-card</code> - presentational only (empty <code>export default {}</code>)</li>
|
|
249
|
+
<li><code>countdown-timer</code> - an interval started in <code>onMount</code> and cleared in <code>onUnmount</code></li>
|
|
250
250
|
</ul>
|
|
251
251
|
|
|
252
252
|
<hr>
|