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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Invoice plugin
|
|
2
|
+
* Invoice plugin - editor view. Create or edit a single invoice.
|
|
3
3
|
*/
|
|
4
4
|
function escapeHtml(s) {
|
|
5
5
|
return String(s ?? '').replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''');
|
|
@@ -77,7 +77,7 @@ export const editorView = {
|
|
|
77
77
|
while (el.firstChild) el.removeChild(el.firstChild);
|
|
78
78
|
const placeholder = document.createElement('option');
|
|
79
79
|
placeholder.value = '';
|
|
80
|
-
placeholder.textContent = '
|
|
80
|
+
placeholder.textContent = '- select -';
|
|
81
81
|
el.appendChild(placeholder);
|
|
82
82
|
for (const item of list) {
|
|
83
83
|
const opt = document.createElement('option');
|
|
@@ -151,7 +151,7 @@ export const editorView = {
|
|
|
151
151
|
const totalCell = document.createElement('td');
|
|
152
152
|
totalCell.style.cssText = 'text-align:right;font-variant-numeric:tabular-nums;';
|
|
153
153
|
totalCell.id = `line-total-${idx}`;
|
|
154
|
-
totalCell.textContent = '
|
|
154
|
+
totalCell.textContent = '-';
|
|
155
155
|
|
|
156
156
|
const removeBtn = document.createElement('button');
|
|
157
157
|
removeBtn.type = 'button';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Invoice plugin
|
|
2
|
+
* Invoice plugin - list view.
|
|
3
3
|
*/
|
|
4
4
|
function escapeHtml(s) {
|
|
5
5
|
return String(s ?? '').replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''');
|
|
@@ -25,7 +25,7 @@ export const indexView = {
|
|
|
25
25
|
|
|
26
26
|
function receiverName(id) {
|
|
27
27
|
const r = receivers.find((x) => x.id === id);
|
|
28
|
-
if (!r) return '
|
|
28
|
+
if (!r) return '-';
|
|
29
29
|
return r.company || r.name || id;
|
|
30
30
|
}
|
|
31
31
|
|
|
@@ -50,13 +50,13 @@ export const indexView = {
|
|
|
50
50
|
columns: [
|
|
51
51
|
{
|
|
52
52
|
key: 'number', title: 'Number', sortable: true,
|
|
53
|
-
render: (v, row) => `<a href="#/plugins/invoice/edit/${escapeHtml(row.id)}" style="font-weight:600;">${escapeHtml(v || '
|
|
53
|
+
render: (v, row) => `<a href="#/plugins/invoice/edit/${escapeHtml(row.id)}" style="font-weight:600;">${escapeHtml(v || '-')}</a>`
|
|
54
54
|
},
|
|
55
55
|
{ key: 'receiverId', title: 'Billed To', sortable: false,
|
|
56
56
|
render: (v) => escapeHtml(receiverName(v))
|
|
57
57
|
},
|
|
58
58
|
{ key: 'issueDate', title: 'Issue Date', sortable: true,
|
|
59
|
-
render: (v) => v ? escapeHtml(D(v).format('DD MMM YYYY')) : '
|
|
59
|
+
render: (v) => v ? escapeHtml(D(v).format('DD MMM YYYY')) : '-'
|
|
60
60
|
},
|
|
61
61
|
{ key: 'totals', title: 'Total', sortable: false,
|
|
62
62
|
render: (totals, row) => `<span style="font-variant-numeric:tabular-nums;">${escapeHtml(fmt(totals?.total ?? 0, row.currency))}</span>`
|
|
@@ -25,11 +25,11 @@ export async function mountPartyView($container, config) {
|
|
|
25
25
|
}
|
|
26
26
|
];
|
|
27
27
|
if (config.fields.some((f) => f.key === 'company')) {
|
|
28
|
-
cols.push({ key: 'company', title: 'Company', sortable: true, render: (v) => escapeHtml(v || '
|
|
28
|
+
cols.push({ key: 'company', title: 'Company', sortable: true, render: (v) => escapeHtml(v || '-') });
|
|
29
29
|
}
|
|
30
30
|
cols.push(
|
|
31
|
-
{ key: 'email', title: 'Email', sortable: true, render: (v) => v ? `<a href="mailto:${escapeHtml(v)}">${escapeHtml(v)}</a>` : '
|
|
32
|
-
{ key: 'vatNumber', title: 'VAT', sortable: false, render: (v) => v ? `<code>${escapeHtml(v)}</code>` : '
|
|
31
|
+
{ key: 'email', title: 'Email', sortable: true, render: (v) => v ? `<a href="mailto:${escapeHtml(v)}">${escapeHtml(v)}</a>` : '-' },
|
|
32
|
+
{ key: 'vatNumber', title: 'VAT', sortable: false, render: (v) => v ? `<code>${escapeHtml(v)}</code>` : '-' },
|
|
33
33
|
{ key: 'id', title: 'Actions', sortable: false,
|
|
34
34
|
render: (id) => `<div style="display:flex;gap:.4rem;">
|
|
35
35
|
<button class="btn btn-sm btn-outline party-edit" data-id="${escapeHtml(id)}"><span data-icon="edit" data-icon-size="14"></span></button>
|
|
@@ -65,19 +65,19 @@
|
|
|
65
65
|
],
|
|
66
66
|
"views": {
|
|
67
67
|
"plugin-invoice-list": {
|
|
68
|
-
"entry": "invoice/admin/views/index.js?v=
|
|
68
|
+
"entry": "invoice/admin/views/index.js?v=9c70ea80",
|
|
69
69
|
"exportName": "indexView"
|
|
70
70
|
},
|
|
71
71
|
"plugin-invoice-editor": {
|
|
72
|
-
"entry": "invoice/admin/views/editor.js?v=
|
|
72
|
+
"entry": "invoice/admin/views/editor.js?v=e5e153c1",
|
|
73
73
|
"exportName": "editorView"
|
|
74
74
|
},
|
|
75
75
|
"plugin-invoice-issuers": {
|
|
76
|
-
"entry": "invoice/admin/views/issuers.js?v=
|
|
76
|
+
"entry": "invoice/admin/views/issuers.js?v=ac69a08a",
|
|
77
77
|
"exportName": "issuersView"
|
|
78
78
|
},
|
|
79
79
|
"plugin-invoice-receivers": {
|
|
80
|
-
"entry": "invoice/admin/views/receivers.js?v=
|
|
80
|
+
"entry": "invoice/admin/views/receivers.js?v=f016e1ff",
|
|
81
81
|
"exportName": "receiversView"
|
|
82
82
|
}
|
|
83
83
|
}
|
|
@@ -101,7 +101,7 @@ export const notesView = {
|
|
|
101
101
|
const ellipsis = v && v.length > 100 ? '\u2026' : '';
|
|
102
102
|
return preview
|
|
103
103
|
? `<span style="font-size:0.87rem;opacity:0.8;">${esc(preview)}${ellipsis}</span>`
|
|
104
|
-
: '<span style="opacity:0.35;"
|
|
104
|
+
: '<span style="opacity:0.35;">-</span>';
|
|
105
105
|
}
|
|
106
106
|
},
|
|
107
107
|
{
|
|
@@ -109,7 +109,7 @@ export const notesView = {
|
|
|
109
109
|
title: 'Categories',
|
|
110
110
|
sortable: false,
|
|
111
111
|
render: (v) => {
|
|
112
|
-
if (!Array.isArray(v) || v.length === 0) return '<span style="opacity:0.35;"
|
|
112
|
+
if (!Array.isArray(v) || v.length === 0) return '<span style="opacity:0.35;">-</span>';
|
|
113
113
|
return v.map((c) =>
|
|
114
114
|
`<span class="badge badge-outline notes-cat-tag" data-cat="${esc(c)}" `
|
|
115
115
|
+ `style="font-size:0.7rem;margin-right:2px;cursor:pointer;">${esc(c)}</span>`
|
|
@@ -122,7 +122,7 @@ export const notesView = {
|
|
|
122
122
|
sortable: true,
|
|
123
123
|
render: (v) => v
|
|
124
124
|
? `<span title="${esc(D(v).format('DD MMM YYYY HH:mm'))}">${esc(D(v).fromNow())}</span>`
|
|
125
|
-
: '
|
|
125
|
+
: '-'
|
|
126
126
|
},
|
|
127
127
|
{
|
|
128
128
|
key: 'id',
|
|
@@ -160,7 +160,7 @@ export const notesView = {
|
|
|
160
160
|
Domma.icons.scan(wrap);
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
// ---- Render category filter bar (DOM methods
|
|
163
|
+
// ---- Render category filter bar (DOM methods - no innerHTML with user data) ----
|
|
164
164
|
function renderCategoryFilter() {
|
|
165
165
|
catFilterEl.textContent = '';
|
|
166
166
|
|
package/plugins/notes/plugin.js
CHANGED
|
@@ -30,7 +30,7 @@ export default async function notesPlugin(fastify, options) {
|
|
|
30
30
|
return items;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
/** GET /api/plugins/notes/items
|
|
33
|
+
/** GET /api/plugins/notes/items - supports ?q= and ?category= */
|
|
34
34
|
fastify.get('/items', { preHandler: [authenticate] }, async (request, reply) => {
|
|
35
35
|
const uid = userId(request);
|
|
36
36
|
const { q, category } = request.query;
|
|
@@ -43,13 +43,13 @@
|
|
|
43
43
|
<label class="form-label">Max results</label>
|
|
44
44
|
<input id="field-max-results" type="number" class="form-input" min="1" max="50"
|
|
45
45
|
placeholder="10">
|
|
46
|
-
<span class="form-hint">Maximum number of results to return per search (1
|
|
46
|
+
<span class="form-hint">Maximum number of results to return per search (1-50).</span>
|
|
47
47
|
</div>
|
|
48
48
|
<div class="col-6">
|
|
49
49
|
<label class="form-label">Minimum query length</label>
|
|
50
50
|
<input id="field-min-query-length" type="number" class="form-input" min="1" max="5"
|
|
51
51
|
placeholder="2">
|
|
52
|
-
<span class="form-hint">Minimum characters required before searching (1
|
|
52
|
+
<span class="form-hint">Minimum characters required before searching (1-5).</span>
|
|
53
53
|
</div>
|
|
54
54
|
</div>
|
|
55
55
|
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
<label class="form-label">Debounce delay (ms)</label>
|
|
59
59
|
<input id="field-debounce-ms" type="number" class="form-input" min="100" max="1000"
|
|
60
60
|
placeholder="300">
|
|
61
|
-
<span class="form-hint">Delay after typing stops before search fires (100
|
|
61
|
+
<span class="form-hint">Delay after typing stops before search fires (100-1000ms).</span>
|
|
62
62
|
</div>
|
|
63
63
|
</div>
|
|
64
64
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Site Search Plugin
|
|
2
|
+
* Site Search Plugin - Server
|
|
3
3
|
*
|
|
4
4
|
* Endpoints (prefix: /api/plugins/site-search):
|
|
5
|
-
* GET /search?q=term
|
|
6
|
-
* GET /settings
|
|
7
|
-
* PUT /settings
|
|
5
|
+
* GET /search?q=term - public: full-text search across all published pages
|
|
6
|
+
* GET /settings - public: return plugin settings (used by inject script)
|
|
7
|
+
* PUT /settings - admin-auth: save user overrides
|
|
8
8
|
*/
|
|
9
9
|
import {listPages} from '../../server/services/content.js';
|
|
10
10
|
import {getPluginSettings, savePluginState} from '../../server/services/plugins.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<div class="survey-results-plugin">
|
|
2
2
|
|
|
3
3
|
<style>
|
|
4
|
-
/* Layout only + real Domma theme tokens
|
|
4
|
+
/* Layout only + real Domma theme tokens - surfaces use .card so the
|
|
5
5
|
active theme is always respected; no hardcoded colours. */
|
|
6
6
|
.survey-results-plugin .sr-head { display:flex; align-items:flex-start; gap:1rem; flex-wrap:wrap; margin-bottom:1.25rem; }
|
|
7
7
|
.survey-results-plugin .sr-head h2 { margin:0 0 0.25rem; }
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<div class="survey-editor-plugin">
|
|
2
2
|
|
|
3
3
|
<style>
|
|
4
|
-
/* Layout only
|
|
4
|
+
/* Layout only - colours/borders come from Domma's themed .card and
|
|
5
5
|
.form-input, so the active theme is always respected. */
|
|
6
6
|
.survey-editor-plugin .se-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem 1.25rem; }
|
|
7
7
|
.survey-editor-plugin .se-span-2 { grid-column: 1 / -1; }
|
|
@@ -90,16 +90,16 @@
|
|
|
90
90
|
<div class="card-body">
|
|
91
91
|
<div class="se-grid">
|
|
92
92
|
<div class="se-field se-span-2">
|
|
93
|
-
<label for="f-intro">Intro (Markdown
|
|
93
|
+
<label for="f-intro">Intro (Markdown - shown above the form)</label>
|
|
94
94
|
<textarea id="f-intro" name="intro" class="form-input" placeholder="## Welcome Thanks for taking a moment to help us improve."></textarea>
|
|
95
95
|
</div>
|
|
96
96
|
<div class="se-field se-span-2">
|
|
97
|
-
<label for="f-footer">Footer (Markdown
|
|
97
|
+
<label for="f-footer">Footer (Markdown - shown below the form)</label>
|
|
98
98
|
<textarea id="f-footer" name="footer" class="form-input" placeholder="Questions? Contact us at hello@example.com"></textarea>
|
|
99
99
|
</div>
|
|
100
100
|
<div class="se-field se-span-2">
|
|
101
101
|
<label for="f-thankYou">Thank-you message (shown after submitting)</label>
|
|
102
|
-
<textarea id="f-thankYou" name="thankYou" class="form-input" placeholder="Thank you
|
|
102
|
+
<textarea id="f-thankYou" name="thankYou" class="form-input" placeholder="Thank you - your response has been recorded."></textarea>
|
|
103
103
|
</div>
|
|
104
104
|
</div>
|
|
105
105
|
</div>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Surveys plugin
|
|
2
|
+
* Surveys plugin - shared audience view.
|
|
3
3
|
*
|
|
4
4
|
* Manages survey contacts and audience groups, plus an import action that pulls
|
|
5
5
|
* the audience from the Contacts plugin.
|
|
@@ -90,15 +90,15 @@ export const audienceView = {
|
|
|
90
90
|
table = T.create($container.find('#audience-table').get(0), {
|
|
91
91
|
data: contacts,
|
|
92
92
|
columns: [
|
|
93
|
-
{key: 'name', title: 'Name', sortable: true, render: (v) => esc(v) || '
|
|
93
|
+
{key: 'name', title: 'Name', sortable: true, render: (v) => esc(v) || '-'},
|
|
94
94
|
{
|
|
95
95
|
key: 'email', title: 'Email', sortable: true,
|
|
96
|
-
render: (v) => v ? `<a href="mailto:${esc(v)}">${esc(v)}</a>` : '
|
|
96
|
+
render: (v) => v ? `<a href="mailto:${esc(v)}">${esc(v)}</a>` : '-'
|
|
97
97
|
},
|
|
98
98
|
{
|
|
99
99
|
key: 'groups', title: 'Groups', sortable: false,
|
|
100
100
|
render: (v) => {
|
|
101
|
-
if (!Array.isArray(v) || !v.length) return '
|
|
101
|
+
if (!Array.isArray(v) || !v.length) return '-';
|
|
102
102
|
return v.map((g) => `<span class="badge badge-primary" style="margin-right:2px;">${esc(g)}</span>`).join('');
|
|
103
103
|
}
|
|
104
104
|
},
|
|
@@ -152,7 +152,7 @@ export const audienceView = {
|
|
|
152
152
|
row.style.cssText = 'padding:0.4rem 0;border-bottom:1px solid var(--dm-border);';
|
|
153
153
|
const badge = document.createElement('span');
|
|
154
154
|
badge.className = 'badge badge-primary';
|
|
155
|
-
badge.textContent = g.name; // textContent
|
|
155
|
+
badge.textContent = g.name; // textContent - safe
|
|
156
156
|
row.appendChild(badge);
|
|
157
157
|
if (g.description) {
|
|
158
158
|
const desc = document.createElement('div');
|
|
@@ -177,7 +177,7 @@ export const audienceView = {
|
|
|
177
177
|
|
|
178
178
|
// Canonical F.create: (blueprintObject, defaultsObject, opts).renderTo(el).
|
|
179
179
|
// Blueprint is keyed by field name; placeholder/hint live under
|
|
180
|
-
// formConfig (proven shape
|
|
180
|
+
// formConfig (proven shape - collection-entries.js). We supply our own
|
|
181
181
|
// buttons (below) and read values from the DOM on save, so the modal's
|
|
182
182
|
// HTML sanitiser never strips an interactive submit button.
|
|
183
183
|
F.create(
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Surveys plugin
|
|
2
|
+
* Surveys plugin - results / statistics dashboard.
|
|
3
3
|
*
|
|
4
4
|
* Renders a response-rate summary, then per-question cards: distribution bars
|
|
5
5
|
* for choice/rating fields and a tidy answer list for free-text fields. Authed
|
|
@@ -76,7 +76,7 @@ export const resultsView = {
|
|
|
76
76
|
|
|
77
77
|
// ---- Header -------------------------------------------------------
|
|
78
78
|
const titleEl = root.querySelector('#results-title');
|
|
79
|
-
if (titleEl) titleEl.textContent = `Results
|
|
79
|
+
if (titleEl) titleEl.textContent = `Results - ${survey?.title || slug}`;
|
|
80
80
|
const subEl = root.querySelector('#results-sub');
|
|
81
81
|
if (subEl) {
|
|
82
82
|
const statusBadge = survey?.status ? ` · ${survey.status}` : '';
|
|
@@ -103,7 +103,7 @@ export const resultsView = {
|
|
|
103
103
|
let questionsHtml;
|
|
104
104
|
|
|
105
105
|
if (!completed && !fields.some((f) => answerCount(f) > 0)) {
|
|
106
|
-
questionsHtml = `<div class="card"><div class="card-body"><p class="sr-empty">No responses yet
|
|
106
|
+
questionsHtml = `<div class="card"><div class="card-body"><p class="sr-empty">No responses yet - once people complete the survey, their answers appear here.</p></div></div>`;
|
|
107
107
|
} else {
|
|
108
108
|
questionsHtml = fields.map((f, idx) => {
|
|
109
109
|
const n = answerCount(f);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Surveys plugin
|
|
2
|
+
* Surveys plugin - campaign list view.
|
|
3
3
|
*
|
|
4
4
|
* Lists survey campaigns in a Domma table with status/mode badges and
|
|
5
5
|
* row actions that navigate to the editor and results views.
|
|
@@ -144,7 +144,7 @@ export const surveysView = {
|
|
|
144
144
|
const audienceBtn = $container.find('#manage-audience').get(0);
|
|
145
145
|
if (audienceBtn) audienceBtn.addEventListener('click', () => { location.hash = '#/plugins/surveys/audience'; });
|
|
146
146
|
|
|
147
|
-
// Row-action delegation (proven pattern
|
|
147
|
+
// Row-action delegation (proven pattern - see admin/js/views/api-tokens.js).
|
|
148
148
|
// Unnamespaced + idempotent via .off()/.on(); namespaced delegation is
|
|
149
149
|
// broken in this codebase.
|
|
150
150
|
$container.off('click', '.btn-edit-survey').on('click', '.btn-edit-survey', function () {
|
|
@@ -12,7 +12,7 @@ import {registerPluginResource} from '../../server/services/permissionRegistry.j
|
|
|
12
12
|
|
|
13
13
|
const col = {createEntry, deleteEntry, getEntry, listEntries, updateEntry};
|
|
14
14
|
|
|
15
|
-
// Register the `surveys` permission family (idempotent
|
|
15
|
+
// Register the `surveys` permission family (idempotent - no-op if already present).
|
|
16
16
|
// Custom roles are NOT back-filled; admins grant it in the role editor (same gotcha
|
|
17
17
|
// as Menus/Projects).
|
|
18
18
|
registerPluginResource({
|
|
@@ -45,19 +45,19 @@
|
|
|
45
45
|
],
|
|
46
46
|
"views": {
|
|
47
47
|
"plugin-surveys": {
|
|
48
|
-
"entry": "surveys/admin/views/surveys.js?v=
|
|
48
|
+
"entry": "surveys/admin/views/surveys.js?v=86946458",
|
|
49
49
|
"exportName": "surveysView"
|
|
50
50
|
},
|
|
51
51
|
"plugin-survey-editor": {
|
|
52
|
-
"entry": "surveys/admin/views/survey-editor.js?v=
|
|
52
|
+
"entry": "surveys/admin/views/survey-editor.js?v=c6b3e1b7",
|
|
53
53
|
"exportName": "surveyEditorView"
|
|
54
54
|
},
|
|
55
55
|
"plugin-survey-audience": {
|
|
56
|
-
"entry": "surveys/admin/views/audience.js?v=
|
|
56
|
+
"entry": "surveys/admin/views/audience.js?v=6aca096f",
|
|
57
57
|
"exportName": "audienceView"
|
|
58
58
|
},
|
|
59
59
|
"plugin-survey-results": {
|
|
60
|
-
"entry": "surveys/admin/views/results.js?v=
|
|
60
|
+
"entry": "surveys/admin/views/results.js?v=97b8e1fd",
|
|
61
61
|
"exportName": "resultsView"
|
|
62
62
|
}
|
|
63
63
|
}
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
],
|
|
33
33
|
"views": {
|
|
34
34
|
"pluginThemeSwitcher": {
|
|
35
|
-
"entry": "theme-switcher/admin/views/theme-switcher.js?v=
|
|
35
|
+
"entry": "theme-switcher/admin/views/theme-switcher.js?v=c906bed1",
|
|
36
36
|
"exportName": "themeSwitcherView"
|
|
37
37
|
}
|
|
38
38
|
}
|
|
@@ -46,11 +46,11 @@
|
|
|
46
46
|
"options": [
|
|
47
47
|
{
|
|
48
48
|
"value": "right-center",
|
|
49
|
-
"label": "Right
|
|
49
|
+
"label": "Right - Centre"
|
|
50
50
|
},
|
|
51
51
|
{
|
|
52
52
|
"value": "left-center",
|
|
53
|
-
"label": "Left
|
|
53
|
+
"label": "Left - Centre"
|
|
54
54
|
},
|
|
55
55
|
{
|
|
56
56
|
"value": "bottom-right",
|
|
@@ -1,30 +1,6 @@
|
|
|
1
1
|
<div class="dm-theme-switcher" id="dm-theme-switcher" role="navigation" aria-label="Theme switcher">
|
|
2
2
|
<button class="dm-ts-trigger" data-tooltip="Switch theme" aria-haspopup="true" aria-expanded="false"></button>
|
|
3
3
|
<div class="dm-ts-options" role="menu">
|
|
4
|
-
<button class="dm-ts-dot dm-ts-dot-ocean-dark" data-theme="ocean-dark" data-tooltip="Ocean Dark"
|
|
5
|
-
aria-label="Ocean Dark"></button>
|
|
6
|
-
<button class="dm-ts-dot dm-ts-dot-ocean-light" data-theme="ocean-light" data-tooltip="Ocean Light"
|
|
7
|
-
aria-label="Ocean Light"></button>
|
|
8
|
-
<button class="dm-ts-dot dm-ts-dot-forest-dark" data-theme="forest-dark" data-tooltip="Forest Dark"
|
|
9
|
-
aria-label="Forest Dark"></button>
|
|
10
|
-
<button class="dm-ts-dot dm-ts-dot-forest-light" data-theme="forest-light" data-tooltip="Forest Light"
|
|
11
|
-
aria-label="Forest Light"></button>
|
|
12
|
-
<button class="dm-ts-dot dm-ts-dot-sunset-dark" data-theme="sunset-dark" data-tooltip="Sunset Dark"
|
|
13
|
-
aria-label="Sunset Dark"></button>
|
|
14
|
-
<button class="dm-ts-dot dm-ts-dot-sunset-light" data-theme="sunset-light" data-tooltip="Sunset Light"
|
|
15
|
-
aria-label="Sunset Light"></button>
|
|
16
|
-
<button class="dm-ts-dot dm-ts-dot-royal-dark" data-theme="royal-dark" data-tooltip="Royal Dark"
|
|
17
|
-
aria-label="Royal Dark"></button>
|
|
18
|
-
<button class="dm-ts-dot dm-ts-dot-royal-light" data-theme="royal-light" data-tooltip="Royal Light"
|
|
19
|
-
aria-label="Royal Light"></button>
|
|
20
|
-
<button class="dm-ts-dot dm-ts-dot-lemon-dark" data-theme="lemon-dark" data-tooltip="Lemon Dark"
|
|
21
|
-
aria-label="Lemon Dark"></button>
|
|
22
|
-
<button class="dm-ts-dot dm-ts-dot-lemon-light" data-theme="lemon-light" data-tooltip="Lemon Light"
|
|
23
|
-
aria-label="Lemon Light"></button>
|
|
24
|
-
<button class="dm-ts-dot dm-ts-dot-silver-dark" data-theme="silver-dark" data-tooltip="Silver Dark"
|
|
25
|
-
aria-label="Silver Dark"></button>
|
|
26
|
-
<button class="dm-ts-dot dm-ts-dot-silver-light" data-theme="silver-light" data-tooltip="Silver Light"
|
|
27
|
-
aria-label="Silver Light"></button>
|
|
28
4
|
<button class="dm-ts-dot dm-ts-dot-charcoal-dark" data-theme="charcoal-dark" data-tooltip="Charcoal Dark"
|
|
29
5
|
aria-label="Charcoal Dark"></button>
|
|
30
6
|
<button class="dm-ts-dot dm-ts-dot-charcoal-light" data-theme="charcoal-light" data-tooltip="Charcoal Light"
|
|
@@ -33,22 +9,46 @@
|
|
|
33
9
|
aria-label="Christmas Dark"></button>
|
|
34
10
|
<button class="dm-ts-dot dm-ts-dot-christmas-light" data-theme="christmas-light" data-tooltip="Christmas Light"
|
|
35
11
|
aria-label="Christmas Light"></button>
|
|
36
|
-
<button class="dm-ts-dot dm-ts-dot-unicorn-dark" data-theme="unicorn-dark" data-tooltip="Unicorn Dark"
|
|
37
|
-
aria-label="Unicorn Dark"></button>
|
|
38
|
-
<button class="dm-ts-dot dm-ts-dot-unicorn-light" data-theme="unicorn-light" data-tooltip="Unicorn Light"
|
|
39
|
-
aria-label="Unicorn Light"></button>
|
|
40
12
|
<button class="dm-ts-dot dm-ts-dot-dreamy-dark" data-theme="dreamy-dark" data-tooltip="Dreamy Dark"
|
|
41
13
|
aria-label="Dreamy Dark"></button>
|
|
42
14
|
<button class="dm-ts-dot dm-ts-dot-dreamy-light" data-theme="dreamy-light" data-tooltip="Dreamy Light"
|
|
43
15
|
aria-label="Dreamy Light"></button>
|
|
16
|
+
<button class="dm-ts-dot dm-ts-dot-forest-dark" data-theme="forest-dark" data-tooltip="Forest Dark"
|
|
17
|
+
aria-label="Forest Dark"></button>
|
|
18
|
+
<button class="dm-ts-dot dm-ts-dot-forest-light" data-theme="forest-light" data-tooltip="Forest Light"
|
|
19
|
+
aria-label="Forest Light"></button>
|
|
44
20
|
<button class="dm-ts-dot dm-ts-dot-grayve-dark" data-theme="grayve-dark" data-tooltip="Grayve Dark"
|
|
45
21
|
aria-label="Grayve Dark"></button>
|
|
46
22
|
<button class="dm-ts-dot dm-ts-dot-grayve-light" data-theme="grayve-light" data-tooltip="Grayve Light"
|
|
47
23
|
aria-label="Grayve Light"></button>
|
|
24
|
+
<button class="dm-ts-dot dm-ts-dot-lemon-dark" data-theme="lemon-dark" data-tooltip="Lemon Dark"
|
|
25
|
+
aria-label="Lemon Dark"></button>
|
|
26
|
+
<button class="dm-ts-dot dm-ts-dot-lemon-light" data-theme="lemon-light" data-tooltip="Lemon Light"
|
|
27
|
+
aria-label="Lemon Light"></button>
|
|
48
28
|
<button class="dm-ts-dot dm-ts-dot-mint-dark" data-theme="mint-dark" data-tooltip="Mint Dark"
|
|
49
29
|
aria-label="Mint Dark"></button>
|
|
50
30
|
<button class="dm-ts-dot dm-ts-dot-mint-light" data-theme="mint-light" data-tooltip="Mint Light"
|
|
51
31
|
aria-label="Mint Light"></button>
|
|
32
|
+
<button class="dm-ts-dot dm-ts-dot-ocean-dark" data-theme="ocean-dark" data-tooltip="Ocean Dark"
|
|
33
|
+
aria-label="Ocean Dark"></button>
|
|
34
|
+
<button class="dm-ts-dot dm-ts-dot-ocean-light" data-theme="ocean-light" data-tooltip="Ocean Light"
|
|
35
|
+
aria-label="Ocean Light"></button>
|
|
36
|
+
<button class="dm-ts-dot dm-ts-dot-royal-dark" data-theme="royal-dark" data-tooltip="Royal Dark"
|
|
37
|
+
aria-label="Royal Dark"></button>
|
|
38
|
+
<button class="dm-ts-dot dm-ts-dot-royal-light" data-theme="royal-light" data-tooltip="Royal Light"
|
|
39
|
+
aria-label="Royal Light"></button>
|
|
40
|
+
<button class="dm-ts-dot dm-ts-dot-silver-dark" data-theme="silver-dark" data-tooltip="Silver Dark"
|
|
41
|
+
aria-label="Silver Dark"></button>
|
|
42
|
+
<button class="dm-ts-dot dm-ts-dot-silver-light" data-theme="silver-light" data-tooltip="Silver Light"
|
|
43
|
+
aria-label="Silver Light"></button>
|
|
44
|
+
<button class="dm-ts-dot dm-ts-dot-sunset-dark" data-theme="sunset-dark" data-tooltip="Sunset Dark"
|
|
45
|
+
aria-label="Sunset Dark"></button>
|
|
46
|
+
<button class="dm-ts-dot dm-ts-dot-sunset-light" data-theme="sunset-light" data-tooltip="Sunset Light"
|
|
47
|
+
aria-label="Sunset Light"></button>
|
|
48
|
+
<button class="dm-ts-dot dm-ts-dot-unicorn-dark" data-theme="unicorn-dark" data-tooltip="Unicorn Dark"
|
|
49
|
+
aria-label="Unicorn Dark"></button>
|
|
50
|
+
<button class="dm-ts-dot dm-ts-dot-unicorn-light" data-theme="unicorn-light" data-tooltip="Unicorn Light"
|
|
51
|
+
aria-label="Unicorn Light"></button>
|
|
52
52
|
<button class="dm-ts-dot dm-ts-dot-wedding-dark" data-theme="wedding-dark" data-tooltip="Wedding Dark"
|
|
53
53
|
aria-label="Wedding Dark"></button>
|
|
54
54
|
<button class="dm-ts-dot dm-ts-dot-wedding-light" data-theme="wedding-light" data-tooltip="Wedding Light"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<style>
|
|
2
2
|
/* ============================================================
|
|
3
|
-
Theme Switcher
|
|
3
|
+
Theme Switcher - Floating Disc
|
|
4
4
|
Position is applied inline by inject-body.html script.
|
|
5
5
|
============================================================ */
|
|
6
6
|
.dm-theme-switcher {
|
package/plugins/todo/plugin.js
CHANGED
|
@@ -78,7 +78,7 @@ export default async function todoPlugin(fastify, options) {
|
|
|
78
78
|
return reply.send(toTodo(updated));
|
|
79
79
|
});
|
|
80
80
|
|
|
81
|
-
/** DELETE /api/plugins/todo/completed
|
|
81
|
+
/** DELETE /api/plugins/todo/completed - must be registered before /:id */
|
|
82
82
|
fastify.delete('/completed', {preHandler: [authenticate]}, async (request, reply) => {
|
|
83
83
|
const uid = userId(request);
|
|
84
84
|
const all = await loadAll(uid);
|
package/public/css/forms.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.fb-form-wrapper{max-width:600px;margin:2rem auto}.fb-form-honeypot{position:absolute;left:-9999px;top:-9999px;width:0;height:0;overflow:hidden;opacity:0;z-index:-1}.fb-form-success{padding:1rem 1.25rem;border-radius:var(--dm-radius-md, 6px);background:color-mix(in srgb,var(--dm-success) 12%,transparent);border:1px solid color-mix(in srgb,var(--dm-success) 30%,transparent);color:var(--dm-success);font-size:.95rem;margin-top:.5rem}.fb-form-error{padding:.75rem 1rem;border-radius:var(--dm-radius-md, 6px);background:color-mix(in srgb,var(--dm-danger) 10%,transparent);border:1px solid color-mix(in srgb,var(--dm-danger) 25%,transparent);color:var(--dm-danger);font-size:.875rem;margin-top:.75rem}.fb-form-loading{opacity:.6;pointer-events:none}.wizard-progress{height:4px;background:var(--dm-border);border-radius:2px;margin-bottom:1rem}.wizard-progress-bar{height:100%;background:var(--dm-primary);border-radius:2px;transition:width .3s ease}.wizard-step-title{font-size:1.1rem;font-weight:600;margin-bottom:.25rem}.wizard-step-description{font-size:.875rem;color:var(--dm-text-muted);margin-bottom:1rem}.wizard-nav{display:flex;justify-content:space-between;gap:.5rem;margin-top:1rem}.fb-field-hidden{display:none!important}.fb-validation-error{color:var(--dm-danger);font-size:.8rem;margin-top:.25rem}.fb-form-wrapper .domma-form-field{margin-bottom:2rem}.fb-form-wrapper .form-group:not(.form-buttons){margin-bottom:2rem}.fb-spacer{height:2rem}.fb-field-required .picker-label:after,.fb-field-required>.form-label:after{content:" *";color:var(--dm-danger)}.fb-field-required .picker-label .picker-required{display:none}
|
|
1
|
+
.fb-form-wrapper{max-width:600px;margin:2rem auto}.fb-form-honeypot{position:absolute;left:-9999px;top:-9999px;width:0;height:0;overflow:hidden;opacity:0;z-index:-1}.fb-form-success{padding:1rem 1.25rem;border-radius:var(--dm-radius-md, 6px);background:color-mix(in srgb,var(--dm-success) 12%,transparent);border:1px solid color-mix(in srgb,var(--dm-success) 30%,transparent);color:var(--dm-success);font-size:.95rem;margin-top:.5rem}.fb-form-error{padding:.75rem 1rem;border-radius:var(--dm-radius-md, 6px);background:color-mix(in srgb,var(--dm-danger) 10%,transparent);border:1px solid color-mix(in srgb,var(--dm-danger) 25%,transparent);color:var(--dm-danger);font-size:.875rem;margin-top:.75rem}.fb-form-loading{opacity:.6;pointer-events:none}.wizard-progress{height:4px;background:var(--dm-border);border-radius:2px;margin-bottom:1rem}.wizard-progress-bar{height:100%;background:var(--dm-primary);border-radius:2px;transition:width .3s ease}.wizard-step-title{font-size:1.1rem;font-weight:600;margin-bottom:.25rem}.wizard-step-description{font-size:.875rem;color:var(--dm-text-muted);margin-bottom:1rem}.wizard-nav{display:flex;justify-content:space-between;gap:.5rem;margin-top:1rem}.fb-field-hidden{display:none!important}.fb-validation-error{color:var(--dm-danger);font-size:.8rem;margin-top:.25rem}.fb-form-wrapper .domma-form-field{margin-bottom:2rem}.fb-form-wrapper .form-group:not(.form-buttons){margin-bottom:2rem}.fb-spacer{height:2rem}.fb-field-required .picker-label:after,.fb-field-required>.form-label:after{content:" *";color:var(--dm-danger)}.fb-field-required .picker-label .picker-required{display:none}.fb-field-invalid>.form-label,.fb-field-invalid .picker-label{color:var(--dm-danger)}.fb-field-invalid .form-input,.fb-field-invalid .form-select,.fb-field-invalid textarea,.fb-field-invalid .picker-options{border-color:var(--dm-danger)}@media(max-width:700px){.fb-form-wrapper form.grid,[data-form-inline] form.grid,.fb-form-wrapper .wizard form.grid,[data-form-inline] .wizard form.grid{grid-template-columns:1fr!important}.fb-form-wrapper form.grid>[class*=col-span-],[data-form-inline] form.grid>[class*=col-span-]{grid-column:span 1 / span 1!important}}.wizard-nav{gap:1rem;flex-wrap:wrap}.wizard-nav .btn{min-width:7.5rem}@media(max-width:480px){.wizard-nav{flex-direction:column-reverse}.wizard-nav .btn{width:100%}}.fb-form-wrapper .form-buttons,[data-form-inline] .form-buttons{display:flex;gap:1rem;flex-wrap:wrap;margin-top:1.25rem}
|