@cosmicdrift/kumiko-bundled-features 0.374.0 → 0.378.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/dist/account-security/constants.d.ts +1 -0
- package/dist/account-security/constants.js +1 -0
- package/dist/account-security/index.d.ts +1 -1
- package/dist/account-security/index.js +1 -1
- package/dist/admin-shell/web/client-plugin.d.ts +1 -1
- package/dist/audit/web/client-plugin.d.ts +1 -1
- package/dist/auth-email-password/mail-notifications.js +1 -1
- package/dist/auth-email-password/web/auth-client.js +1 -1
- package/dist/auth-email-password/web/auth-form-primitives.js +1 -1
- package/dist/auth-email-password/web/default-topbar-actions.js +1 -1
- package/dist/auth-email-password/web/index.js +1 -1
- package/dist/auth-email-password/web/session.js +1 -1
- package/dist/auth-email-password/web/tenant-menu-items.js +1 -1
- package/dist/auth-email-password/web/tenant-switcher.js +1 -1
- package/dist/auth-email-password/web/user-menu.js +1 -1
- package/dist/auth-foundation/env.d.ts +9 -0
- package/dist/auth-foundation/env.js +21 -0
- package/dist/auth-foundation/index.d.ts +1 -0
- package/dist/auth-foundation/index.js +1 -0
- package/dist/auth-mfa/schema/user-mfa.d.ts +6 -6
- package/dist/billing-foundation/consumer-protection/confirmation-mail.js +1 -1
- package/dist/billing-foundation/consumer-protection/termination-pages.js +1 -1
- package/dist/billing-foundation/contact-card.d.ts +2 -0
- package/dist/billing-foundation/contact-card.js +16 -0
- package/dist/billing-foundation/entities.d.ts +8 -8
- package/dist/billing-foundation/handlers/billing-plans.query.js +1 -1
- package/dist/billing-foundation/index.d.ts +1 -1
- package/dist/billing-foundation/plan-catalog.js +1 -0
- package/dist/billing-foundation/projection.d.ts +8 -8
- package/dist/billing-foundation/types.d.ts +11 -0
- package/dist/billing-foundation/validate-options.js +13 -0
- package/dist/billing-foundation/web/billing-contact-plan.d.ts +5 -0
- package/dist/billing-foundation/web/billing-contact-plan.js +17 -0
- package/dist/billing-foundation/web/billing-plans-panel.js +5 -13
- package/dist/billing-foundation/web/cancel-contract-dialog.js +2 -2
- package/dist/billing-foundation/web/checkout-consent-dialog.d.ts +1 -1
- package/dist/billing-foundation/web/checkout-consent-dialog.js +1 -0
- package/dist/billing-foundation/web/client-plugin.d.ts +1 -1
- package/dist/billing-foundation/web/localized-params.d.ts +1 -0
- package/dist/billing-foundation/web/localized-params.js +11 -0
- package/dist/cap-counter/entity.d.ts +1 -1
- package/dist/cap-counter/stock-cap-guard.js +8 -0
- package/dist/cap-overview/web/cap-cards-panel.js +3 -3
- package/dist/cap-overview/web/client-plugin.d.ts +1 -1
- package/dist/channel-email/email-channel.d.ts +2 -1
- package/dist/compliance-profiles/web/client-plugin.d.ts +1 -1
- package/dist/config/feature.js +2 -2
- package/dist/config/table.d.ts +6 -6
- package/dist/config/web/i18n.js +1 -0
- package/dist/custom-fields/entity.d.ts +4 -4
- package/dist/custom-fields/web/client-plugin.d.ts +1 -1
- package/dist/data-retention/schema/tenant-retention-override.d.ts +4 -4
- package/dist/delivery/tables.d.ts +6 -6
- package/dist/delivery/unsubscribe-page.js +1 -1
- package/dist/delivery/web/client-plugin.d.ts +1 -1
- package/dist/delivery/web/delivery-status-cell.js +1 -1
- package/dist/document-ingest-foundation/entity.d.ts +4 -4
- package/dist/feature-toggles/web/client-plugin.d.ts +1 -1
- package/dist/file-provider-s3/env-named-feature.d.ts +17 -0
- package/dist/file-provider-s3/env-named-feature.js +23 -0
- package/dist/file-provider-s3/env-schema.d.ts +7 -0
- package/dist/file-provider-s3/env-schema.js +15 -10
- package/dist/file-provider-s3/index.d.ts +1 -0
- package/dist/file-provider-s3/index.js +1 -0
- package/dist/folders/entity.d.ts +8 -8
- package/dist/folders/web/client-plugin.d.ts +1 -1
- package/dist/form-draft/entity.d.ts +2 -2
- package/dist/host-routing/constants.d.ts +2 -0
- package/dist/host-routing/constants.js +3 -0
- package/dist/host-routing/dispatch.d.ts +1 -1
- package/dist/host-routing/dispatch.js +35 -25
- package/dist/host-routing/feature.js +100 -27
- package/dist/host-routing/host.d.ts +9 -0
- package/dist/host-routing/host.js +24 -2
- package/dist/host-routing/index.d.ts +2 -1
- package/dist/host-routing/index.js +1 -0
- package/dist/host-routing/options.d.ts +14 -0
- package/dist/host-routing/redirects.d.ts +6 -0
- package/dist/host-routing/redirects.js +27 -0
- package/dist/host-routing/tenant-lookup.d.ts +7 -0
- package/dist/host-routing/tenant-lookup.js +39 -0
- package/dist/host-routing/validate-options.js +34 -1
- package/dist/inbound-mail-foundation/entities.d.ts +25 -25
- package/dist/inbound-mail-foundation/feature.js +7 -0
- package/dist/inbound-mail-foundation/handlers/list-accounts.query.d.ts +1 -1
- package/dist/inbound-mail-foundation/handlers/list-accounts.query.js +11 -3
- package/dist/inbound-mail-foundation/i18n.d.ts +3 -0
- package/dist/inbound-mail-foundation/i18n.js +35 -0
- package/dist/inbound-mail-foundation/index.d.ts +1 -0
- package/dist/inbound-mail-foundation/index.js +1 -0
- package/dist/inbound-mail-foundation/projection.d.ts +20 -20
- package/dist/inbound-mail-foundation/screens.d.ts +7 -0
- package/dist/inbound-mail-foundation/screens.js +86 -0
- package/dist/inbound-mail-foundation/types.d.ts +2 -2
- package/dist/jobs/job-run-table.d.ts +6 -6
- package/dist/jobs/web/client-plugin.d.ts +1 -1
- package/dist/ledger/entity.d.ts +13 -13
- package/dist/legal-pages/feature.js +11 -1
- package/dist/legal-pages/layout.d.ts +2 -2
- package/dist/legal-pages/layout.js +4 -4
- package/dist/legal-pages/web/client-plugin.d.ts +1 -1
- package/dist/mail-foundation/feature.d.ts +20 -21
- package/dist/mail-foundation/feature.js +1 -1
- package/dist/mail-foundation/i18n.d.ts +5 -2
- package/dist/mail-foundation/i18n.js +3 -2
- package/dist/mail-transport-smtp/i18n.d.ts +1 -1
- package/dist/mail-transport-smtp/i18n.js +1 -1
- package/dist/managed-pages/table.d.ts +12 -12
- package/dist/managed-pages/web/client-plugin.d.ts +1 -1
- package/dist/notes-history/entity.d.ts +12 -12
- package/dist/notes-history/web/client-plugin.d.ts +1 -1
- package/dist/page-render/branding.js +1 -1
- package/dist/page-render/layout.d.ts +1 -1
- package/dist/page-render/layout.js +2 -2
- package/dist/page-render/markdown.js +1 -1
- package/dist/personal-access-tokens/i18n.js +1 -1
- package/dist/personal-access-tokens/schema/api-token.d.ts +6 -6
- package/dist/personal-access-tokens/screens.js +1 -1
- package/dist/secrets/feature.d.ts +1 -1
- package/dist/secrets/feature.js +3 -3
- package/dist/secrets/table.d.ts +1 -1
- package/dist/seo/sitemap.js +1 -1
- package/dist/sessions/schema/user-session.d.ts +4 -4
- package/dist/shared/mail-template-body.js +1 -1
- package/dist/shared/purge-files-reaching-subject.js +98 -3
- package/dist/tags/entity.d.ts +9 -9
- package/dist/tags/web/client-plugin.d.ts +1 -1
- package/dist/template-resolver/compile-document-body.d.ts +3 -0
- package/dist/template-resolver/compile-document-body.js +50 -3
- package/dist/template-resolver/constants.d.ts +3 -0
- package/dist/template-resolver/constants.js +2 -0
- package/dist/template-resolver/document-blocks.d.ts +5 -0
- package/dist/template-resolver/document-blocks.js +22 -0
- package/dist/template-resolver/document-images.d.ts +2 -0
- package/dist/template-resolver/document-images.js +28 -0
- package/dist/template-resolver/document-ops.d.ts +167 -0
- package/dist/template-resolver/document-ops.js +390 -0
- package/dist/template-resolver/document-sanitizer.d.ts +4 -1
- package/dist/template-resolver/document-sanitizer.js +26 -0
- package/dist/template-resolver/document-schema.d.ts +2 -1
- package/dist/template-resolver/document-schema.js +4 -0
- package/dist/template-resolver/feature.d.ts +11 -0
- package/dist/template-resolver/feature.js +60 -31
- package/dist/template-resolver/handlers/bundle-import.js +1 -0
- package/dist/template-resolver/handlers/collection-item.query.js +2 -1
- package/dist/template-resolver/handlers/collection-list.query.js +2 -1
- package/dist/template-resolver/handlers/collection-set.write.js +2 -2
- package/dist/template-resolver/handlers/collection-shared.d.ts +1 -2
- package/dist/template-resolver/handlers/collection-shared.js +0 -4
- package/dist/template-resolver/handlers/copy-locale.write.d.ts +2 -1
- package/dist/template-resolver/handlers/copy-locale.write.js +67 -63
- package/dist/template-resolver/handlers/discard-draft.write.d.ts +3 -2
- package/dist/template-resolver/handlers/discard-draft.write.js +18 -6
- package/dist/template-resolver/handlers/document-base.d.ts +23 -0
- package/dist/template-resolver/handlers/document-base.js +55 -0
- package/dist/template-resolver/handlers/document-blocks.query.d.ts +22 -0
- package/dist/template-resolver/handlers/document-blocks.query.js +46 -0
- package/dist/template-resolver/handlers/export-bundle.query.d.ts +1 -0
- package/dist/template-resolver/handlers/export-bundle.query.js +9 -2
- package/dist/template-resolver/handlers/import-bundle-system.write.d.ts +1 -0
- package/dist/template-resolver/handlers/import-bundle.write.d.ts +3 -1
- package/dist/template-resolver/handlers/import-bundle.write.js +30 -25
- package/dist/template-resolver/handlers/overview.query.d.ts +2 -1
- package/dist/template-resolver/handlers/overview.query.js +46 -42
- package/dist/template-resolver/handlers/patch-draft.write.d.ts +67 -0
- package/dist/template-resolver/handlers/patch-draft.write.js +111 -0
- package/dist/template-resolver/handlers/preview.query.d.ts +1 -0
- package/dist/template-resolver/handlers/preview.query.js +2 -1
- package/dist/template-resolver/handlers/reset-to-system.write.d.ts +2 -1
- package/dist/template-resolver/handlers/reset-to-system.write.js +51 -44
- package/dist/template-resolver/handlers/resource-link-pdf.write.d.ts +2 -1
- package/dist/template-resolver/handlers/resource-link-pdf.write.js +34 -28
- package/dist/template-resolver/handlers/resource-remove.write.d.ts +2 -1
- package/dist/template-resolver/handlers/resource-remove.write.js +39 -33
- package/dist/template-resolver/handlers/resource-upload.write.d.ts +2 -1
- package/dist/template-resolver/handlers/resource-upload.write.js +104 -96
- package/dist/template-resolver/handlers/send-test-shared.d.ts +5 -0
- package/dist/template-resolver/handlers/send-test-shared.js +19 -0
- package/dist/template-resolver/handlers/send-test-status.query.d.ts +9 -0
- package/dist/template-resolver/handlers/send-test-status.query.js +18 -0
- package/dist/template-resolver/handlers/send-test.write.d.ts +3 -1
- package/dist/template-resolver/handlers/send-test.write.js +87 -88
- package/dist/template-resolver/handlers/set.write.d.ts +2 -1
- package/dist/template-resolver/handlers/set.write.js +94 -90
- package/dist/template-resolver/handlers/template-write.d.ts +2 -0
- package/dist/template-resolver/handlers/template-write.js +14 -2
- package/dist/template-resolver/handlers/toggle-status.write.d.ts +6 -7
- package/dist/template-resolver/handlers/toggle-status.write.js +28 -10
- package/dist/template-resolver/handlers/upsert-tenant.write.d.ts +2 -1
- package/dist/template-resolver/handlers/upsert-tenant.write.js +30 -24
- package/dist/template-resolver/handlers/validate.query.d.ts +10 -4
- package/dist/template-resolver/handlers/validate.query.js +12 -7
- package/dist/template-resolver/index.d.ts +4 -2
- package/dist/template-resolver/index.js +3 -1
- package/dist/template-resolver/{web/placeholder-text.js → placeholder-text.js} +1 -1
- package/dist/template-resolver/qualified-names.d.ts +4 -0
- package/dist/template-resolver/qualified-names.js +4 -0
- package/dist/template-resolver/seeding.d.ts +1 -0
- package/dist/template-resolver/seeding.js +2 -1
- package/dist/template-resolver/table.d.ts +10 -10
- package/dist/template-resolver/template-bundle.d.ts +1 -0
- package/dist/template-resolver/template-bundle.js +6 -1
- package/dist/template-resolver/template-edit-policy.d.ts +22 -0
- package/dist/template-resolver/template-edit-policy.js +45 -0
- package/dist/template-resolver/template-preview.d.ts +4 -1
- package/dist/template-resolver/template-preview.js +23 -5
- package/dist/template-resolver/template-validation.d.ts +2 -1
- package/dist/template-resolver/template-validation.js +34 -14
- package/dist/template-resolver/user-content-table.d.ts +10 -10
- package/dist/template-resolver/web/client-plugin.d.ts +1 -1
- package/dist/template-resolver/web/client-plugin.js +3 -3
- package/dist/template-resolver/web/document-editor-extensions.d.ts +1 -0
- package/dist/template-resolver/web/document-editor-extensions.js +21 -1
- package/dist/template-resolver/web/document-tiptap-editor.d.ts +1 -1
- package/dist/template-resolver/web/document-tiptap-editor.js +23 -7
- package/dist/template-resolver/web/document-toolbar-blocks.d.ts +4 -5
- package/dist/template-resolver/web/document-toolbar-blocks.js +1 -21
- package/dist/template-resolver/web/i18n.js +18 -0
- package/dist/template-resolver/web/placeholder-line-editor.js +2 -2
- package/dist/tenant/invitation-table.d.ts +6 -6
- package/dist/tenant/membership-table.d.ts +4 -4
- package/dist/tenant/schema/tenant.d.ts +6 -6
- package/dist/tenant/web/client-plugin.d.ts +1 -1
- package/dist/tenant/web/member-status-cell.js +1 -1
- package/dist/tier-engine/entity.d.ts +1 -1
- package/dist/tier-engine/tier-resolver.d.ts +1 -1
- package/dist/tier-engine/web/client-plugin.d.ts +1 -1
- package/dist/user/schema/user.d.ts +12 -12
- package/dist/user-data-rights/env.d.ts +5 -0
- package/dist/user-data-rights/env.js +11 -0
- package/dist/user-data-rights/feature.js +4 -2
- package/dist/user-data-rights/index.d.ts +1 -0
- package/dist/user-data-rights/index.js +1 -0
- package/dist/user-data-rights/lib/mail-transport-resolver.js +1 -1
- package/dist/user-data-rights/lib/storage-provider-resolver.js +1 -1
- package/dist/user-data-rights/mail-notifications.js +1 -1
- package/dist/user-data-rights/schema/download-attempt.d.ts +14 -14
- package/dist/user-data-rights/schema/download-token.d.ts +8 -8
- package/dist/user-data-rights/schema/export-job.d.ts +6 -6
- package/dist/user-data-rights/web/client-plugin.d.ts +1 -1
- package/dist/user-data-rights/web/privacy-center-screen.js +2 -2
- package/dist/waitlist/entity.d.ts +14 -14
- package/dist/waitlist/legacy-migrate.d.ts +2 -0
- package/dist/waitlist/legacy-migrate.js +38 -3
- package/package.json +16 -11
- package/src/account-security/changes.json +6 -0
- package/src/auth-foundation/changes.json +6 -0
- package/src/billing-foundation/changes.json +6 -0
- package/src/cap-counter/changes.json +12 -0
- package/src/channel-email/changes.json +6 -0
- package/src/crypto-shredding/changes.json +6 -0
- package/src/file-provider-s3/changes.json +6 -0
- package/src/host-routing/changes.json +6 -0
- package/src/inbound-mail-foundation/changes.json +13 -0
- package/src/legal-pages/changes.json +6 -0
- package/src/mail-foundation/changes.json +6 -0
- package/src/template-resolver/changes.json +38 -0
- package/src/user-data-rights/changes.json +6 -0
- package/src/waitlist/changes.json +6 -0
- /package/dist/template-resolver/{web/placeholder-text.d.ts → placeholder-text.d.ts} +0 -0
|
@@ -14,7 +14,7 @@ export declare const userContentEntryEntity: import("@cosmicdrift/kumiko-types/f
|
|
|
14
14
|
readonly sensitive?: boolean;
|
|
15
15
|
readonly writeOnly?: boolean;
|
|
16
16
|
readonly readAsInstruction?: boolean;
|
|
17
|
-
readonly format?: "email" | "url" | "phone" | "password";
|
|
17
|
+
readonly format?: "email" | "url" | "phone" | "password" | "month";
|
|
18
18
|
readonly default?: string;
|
|
19
19
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
20
20
|
readonly multiline?: boolean | {
|
|
@@ -37,7 +37,7 @@ export declare const userContentEntryEntity: import("@cosmicdrift/kumiko-types/f
|
|
|
37
37
|
readonly sensitive?: boolean;
|
|
38
38
|
readonly writeOnly?: boolean;
|
|
39
39
|
readonly readAsInstruction?: boolean;
|
|
40
|
-
readonly format?: "email" | "url" | "phone" | "password";
|
|
40
|
+
readonly format?: "email" | "url" | "phone" | "password" | "month";
|
|
41
41
|
readonly default?: string;
|
|
42
42
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
43
43
|
readonly multiline?: boolean | {
|
|
@@ -89,7 +89,7 @@ export declare const userContentEntryEntity: import("@cosmicdrift/kumiko-types/f
|
|
|
89
89
|
readonly sensitive?: boolean;
|
|
90
90
|
readonly writeOnly?: boolean;
|
|
91
91
|
readonly readAsInstruction?: boolean;
|
|
92
|
-
readonly format?: "email" | "url" | "phone" | "password";
|
|
92
|
+
readonly format?: "email" | "url" | "phone" | "password" | "month";
|
|
93
93
|
readonly default?: string;
|
|
94
94
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
95
95
|
readonly multiline?: boolean | {
|
|
@@ -112,7 +112,7 @@ export declare const userContentEntryEntity: import("@cosmicdrift/kumiko-types/f
|
|
|
112
112
|
readonly sensitive?: boolean;
|
|
113
113
|
readonly writeOnly?: boolean;
|
|
114
114
|
readonly readAsInstruction?: boolean;
|
|
115
|
-
readonly format?: "email" | "url" | "phone" | "password";
|
|
115
|
+
readonly format?: "email" | "url" | "phone" | "password" | "month";
|
|
116
116
|
readonly default?: string;
|
|
117
117
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
118
118
|
readonly multiline?: boolean | {
|
|
@@ -135,7 +135,7 @@ export declare const userContentEntryEntity: import("@cosmicdrift/kumiko-types/f
|
|
|
135
135
|
readonly sensitive?: boolean;
|
|
136
136
|
readonly writeOnly?: boolean;
|
|
137
137
|
readonly readAsInstruction?: boolean;
|
|
138
|
-
readonly format?: "email" | "url" | "phone" | "password";
|
|
138
|
+
readonly format?: "email" | "url" | "phone" | "password" | "month";
|
|
139
139
|
readonly default?: string;
|
|
140
140
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
141
141
|
readonly multiline?: boolean | {
|
|
@@ -200,7 +200,7 @@ export declare const userContentEntriesTable: import("@cosmicdrift/kumiko-framew
|
|
|
200
200
|
readonly sensitive?: boolean;
|
|
201
201
|
readonly writeOnly?: boolean;
|
|
202
202
|
readonly readAsInstruction?: boolean;
|
|
203
|
-
readonly format?: "email" | "url" | "phone" | "password";
|
|
203
|
+
readonly format?: "email" | "url" | "phone" | "password" | "month";
|
|
204
204
|
readonly default?: string;
|
|
205
205
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
206
206
|
readonly multiline?: boolean | {
|
|
@@ -223,7 +223,7 @@ export declare const userContentEntriesTable: import("@cosmicdrift/kumiko-framew
|
|
|
223
223
|
readonly sensitive?: boolean;
|
|
224
224
|
readonly writeOnly?: boolean;
|
|
225
225
|
readonly readAsInstruction?: boolean;
|
|
226
|
-
readonly format?: "email" | "url" | "phone" | "password";
|
|
226
|
+
readonly format?: "email" | "url" | "phone" | "password" | "month";
|
|
227
227
|
readonly default?: string;
|
|
228
228
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
229
229
|
readonly multiline?: boolean | {
|
|
@@ -275,7 +275,7 @@ export declare const userContentEntriesTable: import("@cosmicdrift/kumiko-framew
|
|
|
275
275
|
readonly sensitive?: boolean;
|
|
276
276
|
readonly writeOnly?: boolean;
|
|
277
277
|
readonly readAsInstruction?: boolean;
|
|
278
|
-
readonly format?: "email" | "url" | "phone" | "password";
|
|
278
|
+
readonly format?: "email" | "url" | "phone" | "password" | "month";
|
|
279
279
|
readonly default?: string;
|
|
280
280
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
281
281
|
readonly multiline?: boolean | {
|
|
@@ -298,7 +298,7 @@ export declare const userContentEntriesTable: import("@cosmicdrift/kumiko-framew
|
|
|
298
298
|
readonly sensitive?: boolean;
|
|
299
299
|
readonly writeOnly?: boolean;
|
|
300
300
|
readonly readAsInstruction?: boolean;
|
|
301
|
-
readonly format?: "email" | "url" | "phone" | "password";
|
|
301
|
+
readonly format?: "email" | "url" | "phone" | "password" | "month";
|
|
302
302
|
readonly default?: string;
|
|
303
303
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
304
304
|
readonly multiline?: boolean | {
|
|
@@ -321,7 +321,7 @@ export declare const userContentEntriesTable: import("@cosmicdrift/kumiko-framew
|
|
|
321
321
|
readonly sensitive?: boolean;
|
|
322
322
|
readonly writeOnly?: boolean;
|
|
323
323
|
readonly readAsInstruction?: boolean;
|
|
324
|
-
readonly format?: "email" | "url" | "phone" | "password";
|
|
324
|
+
readonly format?: "email" | "url" | "phone" | "password" | "month";
|
|
325
325
|
readonly default?: string;
|
|
326
326
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
327
327
|
readonly multiline?: boolean | {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { TreeNode } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
|
-
import { type ClientFeatureDefinition } from "@cosmicdrift/kumiko-renderer
|
|
2
|
+
import { type ClientFeatureDefinition } from "@cosmicdrift/kumiko-renderer/web";
|
|
3
3
|
export type BlockSummary = {
|
|
4
4
|
readonly slug: string;
|
|
5
5
|
readonly locale: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { EMPTY_VALUE_PLACEHOLDER } from "@cosmicdrift/kumiko-headless";
|
|
2
|
+
import { EMPTY_VALUE_PLACEHOLDER } from "@cosmicdrift/kumiko-renderer/headless";
|
|
3
3
|
// @runtime client
|
|
4
4
|
// Client feature factory for the text-block content tree. Apps mount it via
|
|
5
5
|
// createKumikoApp({ clientFeatures: [textBlocksClient()] }); it loads the
|
|
@@ -12,9 +12,9 @@ import { EMPTY_VALUE_PLACEHOLDER } from "@cosmicdrift/kumiko-headless";
|
|
|
12
12
|
// **State**: TreeNode.state = "filled" when content is set, otherwise "stub"
|
|
13
13
|
// (a hint that the slug exists but is empty).
|
|
14
14
|
import { useShellUser } from "@cosmicdrift/kumiko-bundled-features/auth-email-password/web";
|
|
15
|
-
import { CSRF_HEADER_NAME, readCsrfToken } from "@cosmicdrift/kumiko-dispatcher-live";
|
|
16
15
|
import { ContentPreview, useAppFeatures, useContentEditor, useDispatcher, usePrimitives, useQuery, useTranslation, } from "@cosmicdrift/kumiko-renderer";
|
|
17
|
-
import {
|
|
16
|
+
import { CSRF_HEADER_NAME, readCsrfToken } from "@cosmicdrift/kumiko-renderer/live";
|
|
17
|
+
import { PlainContentEditor, RichContentEditor, } from "@cosmicdrift/kumiko-renderer/web";
|
|
18
18
|
import { useEffect, useId, useState } from "react";
|
|
19
19
|
import { collectionHandlerName, collectionQueryName, TemplateResolverHandlers, TemplateResolverQueries, } from "../qualified-names.js";
|
|
20
20
|
import { DocumentBlocksContext, DocumentContentEditor } from "./document-editor.js";
|
|
@@ -7,6 +7,7 @@ export type DocumentEditorLabels = {
|
|
|
7
7
|
readonly pageBreak: string;
|
|
8
8
|
readonly button?: string;
|
|
9
9
|
readonly steps?: string;
|
|
10
|
+
readonly images?: string;
|
|
10
11
|
/** Canvas block label of an image, e.g. "Image · inline". */
|
|
11
12
|
readonly imageBlock?: string;
|
|
12
13
|
readonly variableLabels?: Readonly<Record<string, string>>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ListKeymap } from "@tiptap/extension-list";
|
|
2
2
|
import { Dropcursor, Gapcursor, Placeholder, UndoRedo } from "@tiptap/extensions";
|
|
3
|
-
import { DocumentButton, DocumentPageBreak, DocumentResource, DocumentSteps, DocumentVariable, documentExtensions, } from "../document-schema.js";
|
|
3
|
+
import { DocumentButton, DocumentImages, DocumentPageBreak, DocumentResource, DocumentSteps, DocumentVariable, documentExtensions, } from "../document-schema.js";
|
|
4
4
|
import { readDocumentStepsAttribute } from "../document-steps.js";
|
|
5
5
|
const DOCUMENT_RESOURCE_SIZE_TOKEN = "{size}";
|
|
6
6
|
export const DOCUMENT_BLOCK_ATTRIBUTE = "data-document-block";
|
|
@@ -134,6 +134,24 @@ function createStepsView(labels) {
|
|
|
134
134
|
return { dom };
|
|
135
135
|
};
|
|
136
136
|
}
|
|
137
|
+
// A sketch only: the photos are record data, known at render time.
|
|
138
|
+
function createImagesView(labels) {
|
|
139
|
+
return ({ node }) => {
|
|
140
|
+
const dom = createElementWithClass("div", "relative my-3 rounded border border-dashed border-input px-3 pb-3 pt-4");
|
|
141
|
+
dom.setAttribute(DOCUMENT_BLOCK_ATTRIBUTE, "");
|
|
142
|
+
dom.contentEditable = "false";
|
|
143
|
+
const variable = String(node.attrs["variable"]);
|
|
144
|
+
const variableLabels = labels.variableLabels ?? {};
|
|
145
|
+
const variableLabel = Object.hasOwn(variableLabels, variable)
|
|
146
|
+
? variableLabels[variable]
|
|
147
|
+
: undefined;
|
|
148
|
+
dom.append(createBlockLabel(`${labels.images ?? "Photos"} · ${variableLabel ?? variable}`));
|
|
149
|
+
const grid = createElementWithClass("div", "grid grid-cols-2 gap-1.5");
|
|
150
|
+
grid.append(createElementWithClass("div", "h-12 rounded bg-muted"), createElementWithClass("div", "h-12 rounded bg-muted"));
|
|
151
|
+
dom.append(grid);
|
|
152
|
+
return { dom };
|
|
153
|
+
};
|
|
154
|
+
}
|
|
137
155
|
// Replaced by name, not appended: the schema must keep exactly one node per
|
|
138
156
|
// name, and only the editor view differs from the shared document schema.
|
|
139
157
|
export function createDocumentEditorExtensions(labels) {
|
|
@@ -151,6 +169,8 @@ export function createDocumentEditorExtensions(labels) {
|
|
|
151
169
|
: extension;
|
|
152
170
|
case DocumentSteps.name:
|
|
153
171
|
return DocumentSteps.extend({ addNodeView: () => createStepsView(labels) });
|
|
172
|
+
case DocumentImages.name:
|
|
173
|
+
return DocumentImages.extend({ addNodeView: () => createImagesView(labels) });
|
|
154
174
|
case DocumentPageBreak.name:
|
|
155
175
|
return DocumentPageBreak.extend({
|
|
156
176
|
addNodeView: () => createPageBreakView(labels.pageBreak),
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { type ReactNode } from "react";
|
|
2
2
|
import { type DocumentEditorProps } from "./document-toolbar-blocks.ts";
|
|
3
|
-
export default function DocumentTiptapEditor({ id, value, onChange, variables, readOnly, blocks, variableLabels, systemVariables, resourcePreviews, chrome, toolbar, renderPaper, toolbarHost, onEditorReady, }: DocumentEditorProps): ReactNode;
|
|
3
|
+
export default function DocumentTiptapEditor({ id, value, onChange, variables, readOnly, blocks: configuredBlocks, imageVariables, variableLabels, systemVariables, resourcePreviews, chrome, toolbar, renderPaper, toolbarHost, onEditorReady, }: DocumentEditorProps): ReactNode;
|
|
@@ -6,11 +6,11 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
|
|
|
6
6
|
// collection is rendered. Variables are inserted as `variable` nodes only,
|
|
7
7
|
// never as `{{name}}` text, so the sanitizer's schema keeps them.
|
|
8
8
|
import { TextareaContentEditor, usePrimitives, useTranslation, VariableChips, } from "@cosmicdrift/kumiko-renderer";
|
|
9
|
-
import { cn } from "@cosmicdrift/kumiko-renderer
|
|
9
|
+
import { cn } from "@cosmicdrift/kumiko-renderer/web";
|
|
10
10
|
import { isOneOf } from "@cosmicdrift/kumiko-types/type-guards";
|
|
11
11
|
import { EditorContent, useEditor, useEditorState } from "@tiptap/react";
|
|
12
12
|
import { BubbleMenu } from "@tiptap/react/menus";
|
|
13
|
-
import { AlignCenter, AlignJustify, AlignLeft, AlignRight, Bold as BoldIcon, Braces, ChevronDown, Image as ImageIcon, Italic as ItalicIcon, Link as LinkIcon, List, ListChecks, ListOrdered, Minus, MousePointerClick, Repeat, Scissors, Table as TableIcon, Underline as UnderlineIcon, } from "lucide-react";
|
|
13
|
+
import { AlignCenter, AlignJustify, AlignLeft, AlignRight, Bold as BoldIcon, Braces, ChevronDown, GalleryThumbnails, Image as ImageIcon, Italic as ItalicIcon, Link as LinkIcon, List, ListChecks, ListOrdered, Minus, MousePointerClick, Repeat, Scissors, Table as TableIcon, Underline as UnderlineIcon, } from "lucide-react";
|
|
14
14
|
import { Fragment, useEffect, useMemo, useState } from "react";
|
|
15
15
|
import { createPortal } from "react-dom";
|
|
16
16
|
import { DOCUMENT_TEXT_ALIGNMENTS, isAllowedDocumentLinkHref, isDocumentPlaceholderHref, isDocumentReferenceName, isDocumentResourceKey, } from "../document-schema.js";
|
|
@@ -35,6 +35,7 @@ const BLOCK_PANEL = {
|
|
|
35
35
|
repeat: "repeat",
|
|
36
36
|
align: "align",
|
|
37
37
|
steps: "steps",
|
|
38
|
+
images: "images",
|
|
38
39
|
};
|
|
39
40
|
const ALIGNMENT_ICONS = {
|
|
40
41
|
left: _jsx(AlignLeft, { size: 16 }),
|
|
@@ -243,7 +244,11 @@ function InsertPanel({ editor, editorId, kind, variables, variableLabels, onClos
|
|
|
243
244
|
}
|
|
244
245
|
insertAndClose({ type: "steps", attrs: { variable: selectedName, steps } });
|
|
245
246
|
};
|
|
246
|
-
const needsVariables = kind === "button" ||
|
|
247
|
+
const needsVariables = kind === "button" ||
|
|
248
|
+
kind === "repeat" ||
|
|
249
|
+
kind === "placeholder" ||
|
|
250
|
+
kind === "steps" ||
|
|
251
|
+
kind === "images";
|
|
247
252
|
const noVariables = needsVariables && selectable.length === 0;
|
|
248
253
|
const idPrefix = `${editorId}-panel`;
|
|
249
254
|
return (_jsxs("div", { className: "flex flex-col gap-2 border-b border-input bg-muted/40 p-2", children: [noVariables && (_jsx("p", { className: "text-sm text-muted-foreground", children: t("template-resolver.documentEditor.noVariables") })), kind === "link" && (_jsx(Field, { id: `${idPrefix}-href`, label: t("template-resolver.documentEditor.linkHref"), children: _jsx(Input, { kind: "text", id: `${idPrefix}-href`, name: "href", value: href, onChange: setHref, placeholder: t("template-resolver.documentEditor.linkHrefPlaceholder") }) })), kind === "placeholder" && !noVariables && (_jsx("div", { className: "flex flex-wrap gap-1", children: _jsx(VariableChips, { variables: selectable, labels: variableLabels, onInsert: (name) => insertAndClose({ type: "variable", attrs: { name } }) }) })), kind === "align" && (_jsx("div", { className: "flex flex-wrap gap-1", children: DOCUMENT_TEXT_ALIGNMENTS.map((alignment) => (_jsxs(Button, { type: "button", variant: "secondary", size: "sm", onClick: () => {
|
|
@@ -254,7 +259,7 @@ function InsertPanel({ editor, editorId, kind, variables, variableLabels, onClos
|
|
|
254
259
|
.updateAttributes("heading", { textAlign: alignment })
|
|
255
260
|
.run();
|
|
256
261
|
onClose();
|
|
257
|
-
}, children: [ALIGNMENT_ICONS[alignment], t(ALIGNMENT_LABEL_KEYS[alignment])] }, alignment))) })), kind === "image" && (_jsxs(_Fragment, { children: [_jsx(Field, { id: `${idPrefix}-resource`, label: t("template-resolver.documentEditor.resourceKey"), children: _jsx(Input, { kind: "text", id: `${idPrefix}-resource`, name: "resource", value: resource, onChange: setResource }) }), _jsx(Field, { id: `${idPrefix}-alt`, label: t("template-resolver.documentEditor.imageAlt"), children: _jsx(Input, { kind: "text", id: `${idPrefix}-alt`, name: "alt", value: alt, onChange: setAlt }) })] })), kind === "button" && !noVariables && (_jsxs(_Fragment, { children: [_jsx(NameSelect, { id: `${idPrefix}-target`, label: t("template-resolver.documentEditor.buttonTarget"), names: selectable, labels: variableLabels, value: selectedName, onChange: setChosenName }), _jsx(Field, { id: `${idPrefix}-text`, label: t("template-resolver.documentEditor.buttonText"), children: _jsx(Input, { kind: "text", id: `${idPrefix}-text`, name: "text", value: buttonText, onChange: setButtonText }) })] })), kind === "repeat" && !noVariables && (_jsx(NameSelect, { id: `${idPrefix}-list`, label: t("template-resolver.documentEditor.repeatList"), names: selectable, labels: variableLabels, value: selectedName, onChange: setChosenName })), kind === "steps" && !noVariables && (_jsxs(_Fragment, { children: [_jsx(NameSelect, { id: `${idPrefix}-steps-variable`, label: t("template-resolver.documentEditor.stepsVariable"), names: selectable, labels: variableLabels, value: selectedName, onChange: setChosenName }), _jsx(Field, { id: `${idPrefix}-steps-list`, label: t("template-resolver.documentEditor.stepsList"), children: _jsx(Input, { kind: "text", id: `${idPrefix}-steps-list`, name: "steps", value: stepsText, onChange: setStepsText }) })] })), error !== null && (_jsx("p", { role: "alert", className: "text-sm text-destructive", children: error })), _jsx("div", { className: "flex flex-wrap gap-2", children: _jsx(PanelActions, { onCancel: onClose, ...(kind === "link" && { onInsert: submitLink }), ...(kind === "link" &&
|
|
262
|
+
}, children: [ALIGNMENT_ICONS[alignment], t(ALIGNMENT_LABEL_KEYS[alignment])] }, alignment))) })), kind === "image" && (_jsxs(_Fragment, { children: [_jsx(Field, { id: `${idPrefix}-resource`, label: t("template-resolver.documentEditor.resourceKey"), children: _jsx(Input, { kind: "text", id: `${idPrefix}-resource`, name: "resource", value: resource, onChange: setResource }) }), _jsx(Field, { id: `${idPrefix}-alt`, label: t("template-resolver.documentEditor.imageAlt"), children: _jsx(Input, { kind: "text", id: `${idPrefix}-alt`, name: "alt", value: alt, onChange: setAlt }) })] })), kind === "button" && !noVariables && (_jsxs(_Fragment, { children: [_jsx(NameSelect, { id: `${idPrefix}-target`, label: t("template-resolver.documentEditor.buttonTarget"), names: selectable, labels: variableLabels, value: selectedName, onChange: setChosenName }), _jsx(Field, { id: `${idPrefix}-text`, label: t("template-resolver.documentEditor.buttonText"), children: _jsx(Input, { kind: "text", id: `${idPrefix}-text`, name: "text", value: buttonText, onChange: setButtonText }) })] })), kind === "repeat" && !noVariables && (_jsx(NameSelect, { id: `${idPrefix}-list`, label: t("template-resolver.documentEditor.repeatList"), names: selectable, labels: variableLabels, value: selectedName, onChange: setChosenName })), kind === "images" && !noVariables && (_jsx(NameSelect, { id: `${idPrefix}-images-variable`, label: t("template-resolver.documentEditor.imagesVariable"), names: selectable, labels: variableLabels, value: selectedName, onChange: setChosenName })), kind === "steps" && !noVariables && (_jsxs(_Fragment, { children: [_jsx(NameSelect, { id: `${idPrefix}-steps-variable`, label: t("template-resolver.documentEditor.stepsVariable"), names: selectable, labels: variableLabels, value: selectedName, onChange: setChosenName }), _jsx(Field, { id: `${idPrefix}-steps-list`, label: t("template-resolver.documentEditor.stepsList"), children: _jsx(Input, { kind: "text", id: `${idPrefix}-steps-list`, name: "steps", value: stepsText, onChange: setStepsText }) })] })), error !== null && (_jsx("p", { role: "alert", className: "text-sm text-destructive", children: error })), _jsx("div", { className: "flex flex-wrap gap-2", children: _jsx(PanelActions, { onCancel: onClose, ...(kind === "link" && { onInsert: submitLink }), ...(kind === "link" &&
|
|
258
263
|
editor.isActive("link") && {
|
|
259
264
|
onRemoveLink: () => {
|
|
260
265
|
editor.chain().focus().extendMarkRange("link").unsetLink().run();
|
|
@@ -268,9 +273,12 @@ function InsertPanel({ editor, editorId, kind, variables, variableLabels, onClos
|
|
|
268
273
|
content: buttonText ? [{ type: "text", text: buttonText }] : [],
|
|
269
274
|
}),
|
|
270
275
|
}), ...(kind === "repeat" &&
|
|
271
|
-
!noVariables && { onInsert: () => insertAndClose(repeatTableContent(selectedName)) }), ...(kind === "steps" && !noVariables && { onInsert: submitSteps })
|
|
276
|
+
!noVariables && { onInsert: () => insertAndClose(repeatTableContent(selectedName)) }), ...(kind === "steps" && !noVariables && { onInsert: submitSteps }), ...(kind === "images" &&
|
|
277
|
+
!noVariables && {
|
|
278
|
+
onInsert: () => insertAndClose({ type: "images", attrs: { variable: selectedName } }),
|
|
279
|
+
}) }) })] }));
|
|
272
280
|
}
|
|
273
|
-
export default function DocumentTiptapEditor({ id, value, onChange, variables, readOnly, blocks = MAIL_DOCUMENT_BLOCKS, variableLabels = NO_LABELS, systemVariables = NO_NAMES, resourcePreviews = NO_PREVIEWS, chrome = "default", toolbar = "full", renderPaper, toolbarHost, onEditorReady, }) {
|
|
281
|
+
export default function DocumentTiptapEditor({ id, value, onChange, variables, readOnly, blocks: configuredBlocks = MAIL_DOCUMENT_BLOCKS, imageVariables = NO_NAMES, variableLabels = NO_LABELS, systemVariables = NO_NAMES, resourcePreviews = NO_PREVIEWS, chrome = "default", toolbar = "full", renderPaper, toolbarHost, onEditorReady, }) {
|
|
274
282
|
const t = useTranslation();
|
|
275
283
|
const { ActionOverflowMenu, Button, Field, Input } = usePrimitives();
|
|
276
284
|
const [openPanel, setOpenPanel] = useState(null);
|
|
@@ -279,12 +287,17 @@ export default function DocumentTiptapEditor({ id, value, onChange, variables, r
|
|
|
279
287
|
const canvas = chrome === "canvas";
|
|
280
288
|
const compact = toolbar === "compact" && !canvas;
|
|
281
289
|
const hosted = toolbarHost !== undefined;
|
|
290
|
+
// A photo block needs an images variable to bind to; without one the button would open an empty panel.
|
|
291
|
+
const blocks = imageVariables.length === 0
|
|
292
|
+
? configuredBlocks.filter((block) => block !== "images")
|
|
293
|
+
: configuredBlocks;
|
|
282
294
|
const placeholderLabel = t("template-resolver.documentEditor.placeholder");
|
|
283
295
|
const imageLabel = t("template-resolver.documentEditor.image");
|
|
284
296
|
const imageBlockLabel = t("template-resolver.documentEditor.imageBlock");
|
|
285
297
|
const pageBreakLabel = t("template-resolver.documentEditor.pageBreak");
|
|
286
298
|
const buttonLabel = t("template-resolver.documentEditor.button");
|
|
287
299
|
const stepsLabel = t("template-resolver.documentEditor.steps");
|
|
300
|
+
const imagesLabel = t("template-resolver.documentEditor.images");
|
|
288
301
|
const stableLabels = useStableByKey(variableLabels, JSON.stringify(variableLabels));
|
|
289
302
|
const stableSystem = useStableByKey(systemVariables, systemVariables.join("\n"));
|
|
290
303
|
const stablePreviews = useStableByKey(resourcePreviews, previewsKey(resourcePreviews));
|
|
@@ -294,6 +307,7 @@ export default function DocumentTiptapEditor({ id, value, onChange, variables, r
|
|
|
294
307
|
pageBreak: pageBreakLabel,
|
|
295
308
|
button: buttonLabel,
|
|
296
309
|
steps: stepsLabel,
|
|
310
|
+
images: imagesLabel,
|
|
297
311
|
imageBlock: imageBlockLabel,
|
|
298
312
|
variableLabels: stableLabels,
|
|
299
313
|
systemVariables: stableSystem,
|
|
@@ -306,6 +320,7 @@ export default function DocumentTiptapEditor({ id, value, onChange, variables, r
|
|
|
306
320
|
pageBreakLabel,
|
|
307
321
|
buttonLabel,
|
|
308
322
|
stepsLabel,
|
|
323
|
+
imagesLabel,
|
|
309
324
|
stableLabels,
|
|
310
325
|
stableSystem,
|
|
311
326
|
stablePreviews,
|
|
@@ -415,6 +430,7 @@ export default function DocumentTiptapEditor({ id, value, onChange, variables, r
|
|
|
415
430
|
pageBreak: { label: pageBreakLabel, icon: _jsx(Scissors, { size: 16 }) },
|
|
416
431
|
align: { label: t("template-resolver.documentEditor.align"), icon: _jsx(AlignLeft, { size: 16 }) },
|
|
417
432
|
steps: { label: stepsLabel, icon: _jsx(ListChecks, { size: 16 }) },
|
|
433
|
+
images: { label: imagesLabel, icon: _jsx(GalleryThumbnails, { size: 16 }) },
|
|
418
434
|
};
|
|
419
435
|
const repeatTable = activeState?.repeatTable ?? null;
|
|
420
436
|
const repeatListLabel = repeatTable !== null && repeatTable.lists.length === 1
|
|
@@ -507,7 +523,7 @@ export default function DocumentTiptapEditor({ id, value, onChange, variables, r
|
|
|
507
523
|
: t("template-resolver.documentEditor.buttonTarget"), ": ", selectedBlock.type === "button" ? (_jsx("strong", { children: buttonTargetLabel(selectedBlock.detail, variableLabels) })) : (_jsx("code", { children: selectedBlock.detail }))] }), _jsx(Button, { type: "button", size: "sm", variant: "danger-ghost", onClick: () => {
|
|
508
524
|
editor.chain().focus().deleteNode(selectedBlock.type).run();
|
|
509
525
|
}, children: t("template-resolver.documentEditor.removeBlock") })] })) : (repeatTable !== null && (_jsxs("div", { "data-testid": "document-repeat-bar", className: BUBBLE_BAR_CLASS, children: [_jsx("span", { className: "px-1.5 text-[10px] uppercase tracking-wide text-muted-foreground", children: repeatBarLabel }), _jsx(Button, { type: "button", variant: "secondary", size: "sm", pressed: repeatTable.headerRepeats, onClick: () => toggleRepeatHeader(editor), children: t("template-resolver.documentEditor.repeatHeader") })] }))) }, mountKeyOf(editor)));
|
|
510
|
-
const insertPanel = openPanel !== null && !readOnly && (_jsx(InsertPanel, { editor: editor, editorId: id, kind: openPanel, variables: variables, variableLabels: stableLabels, onClose: () => setOpenPanel(null) }, openPanel));
|
|
526
|
+
const insertPanel = openPanel !== null && !readOnly && (_jsx(InsertPanel, { editor: editor, editorId: id, kind: openPanel, variables: openPanel === "images" ? imageVariables : variables, variableLabels: stableLabels, onClose: () => setOpenPanel(null) }, openPanel));
|
|
511
527
|
if (hosted) {
|
|
512
528
|
return (_jsxs(_Fragment, { children: [toolbarHost !== null &&
|
|
513
529
|
createPortal(_jsxs(_Fragment, { children: [toolbarBar, insertPanel] }), toolbarHost), !readOnly && bubbleMenu, editorContent] }));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ContentEditorProps } from "@cosmicdrift/kumiko-renderer";
|
|
2
2
|
import type { ReactNode } from "react";
|
|
3
|
-
|
|
3
|
+
import type { DocumentToolbarBlock } from "../document-blocks.ts";
|
|
4
4
|
/** Imperative access for an outside panel (placeholder list, resource list). */
|
|
5
5
|
export type DocumentEditorHandle = {
|
|
6
6
|
readonly insertPlaceholder: (name: string) => void;
|
|
@@ -17,6 +17,8 @@ export type DocumentResourcePreview = {
|
|
|
17
17
|
export type DocumentEditorChrome = "default" | "canvas";
|
|
18
18
|
export type DocumentEditorProps = ContentEditorProps & {
|
|
19
19
|
readonly blocks?: readonly DocumentToolbarBlock[];
|
|
20
|
+
/** Names of the template's images variables; the photo block offers exactly these and is hidden without any. */
|
|
21
|
+
readonly imageVariables?: readonly string[];
|
|
20
22
|
/** Display label per variable name, as inserted (list item fields use the
|
|
21
23
|
* dotted form, e.g. "lines.description"). A chip shows label and name. */
|
|
22
24
|
readonly variableLabels?: Readonly<Record<string, string>>;
|
|
@@ -35,7 +37,4 @@ export type DocumentEditorProps = ContentEditorProps & {
|
|
|
35
37
|
/** Called with the handle once the editor exists and with null when it is destroyed (unmount or rebuild), so a held handle never outlives its editor. */
|
|
36
38
|
readonly onEditorReady?: (handle: DocumentEditorHandle | null) => void;
|
|
37
39
|
};
|
|
38
|
-
export
|
|
39
|
-
export declare const PDF_DOCUMENT_BLOCKS: readonly ["align", "image", "table", "divider", "repeat", "steps", "pageBreak"];
|
|
40
|
-
/** Block set for a template-resource kind; every kind except "document-pdf" gets the mail set. */
|
|
41
|
-
export declare function documentBlocksForKind(kind: string | undefined): readonly DocumentToolbarBlock[];
|
|
40
|
+
export { type DocumentToolbarBlock, documentBlocksForKind, MAIL_DOCUMENT_BLOCKS, PDF_DOCUMENT_BLOCKS, } from "../document-blocks.ts";
|
|
@@ -1,21 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
"image",
|
|
3
|
-
"table",
|
|
4
|
-
"button",
|
|
5
|
-
"divider",
|
|
6
|
-
"repeat",
|
|
7
|
-
"steps",
|
|
8
|
-
];
|
|
9
|
-
export const PDF_DOCUMENT_BLOCKS = [
|
|
10
|
-
"align",
|
|
11
|
-
"image",
|
|
12
|
-
"table",
|
|
13
|
-
"divider",
|
|
14
|
-
"repeat",
|
|
15
|
-
"steps",
|
|
16
|
-
"pageBreak",
|
|
17
|
-
];
|
|
18
|
-
/** Block set for a template-resource kind; every kind except "document-pdf" gets the mail set. */
|
|
19
|
-
export function documentBlocksForKind(kind) {
|
|
20
|
-
return kind === "document-pdf" ? PDF_DOCUMENT_BLOCKS : MAIL_DOCUMENT_BLOCKS;
|
|
21
|
-
}
|
|
1
|
+
export { documentBlocksForKind, MAIL_DOCUMENT_BLOCKS, PDF_DOCUMENT_BLOCKS, } from "../document-blocks.js";
|
|
@@ -39,6 +39,8 @@ export const defaultTranslations = {
|
|
|
39
39
|
"template-resolver.documentEditor.removeLink": "Remove link",
|
|
40
40
|
"template-resolver.documentEditor.repeat": "Repeat",
|
|
41
41
|
"template-resolver.documentEditor.repeatList": "List to repeat",
|
|
42
|
+
"template-resolver.documentEditor.images": "Photos",
|
|
43
|
+
"template-resolver.documentEditor.imagesVariable": "Photos from",
|
|
42
44
|
"template-resolver.documentEditor.steps": "Steps",
|
|
43
45
|
"template-resolver.documentEditor.stepsVariable": "Current step from",
|
|
44
46
|
"template-resolver.documentEditor.stepsList": "Steps, separated by commas (value=label)",
|
|
@@ -52,6 +54,7 @@ export const defaultTranslations = {
|
|
|
52
54
|
"template-resolver.editor.saving": "Saving…",
|
|
53
55
|
"template-resolver.editor.created": "Created.",
|
|
54
56
|
"template-resolver.editor.saved": "Saved.",
|
|
57
|
+
"templateResolver.errors.document.imagesBlockPdfOnly": "Photo blocks are only allowed in PDF documents.",
|
|
55
58
|
"templateResolver.errors.document.buttonHrefNotPlaceholder": "The button target “{detail}” must be a placeholder.",
|
|
56
59
|
"templateResolver.errors.document.disallowedLinkHref": "Link target “{detail}” is not allowed; use https, http, mailto, tel or a placeholder.",
|
|
57
60
|
"templateResolver.errors.document.documentRequiresHtmlFormat": "This template kind requires the html format, got “{detail}”.",
|
|
@@ -66,6 +69,20 @@ export const defaultTranslations = {
|
|
|
66
69
|
"templateResolver.checks.sizeUnderCap": "The mail is within the 10 MiB size limit",
|
|
67
70
|
"templateResolver.checks.requiredPlaceholders": "All required placeholders are used",
|
|
68
71
|
"templateResolver.errors.preview.renderFailed": "The preview could not be rendered.",
|
|
72
|
+
"templateResolver.errors.patch.unknownBlock": "The block {blockId} does not exist in the template.",
|
|
73
|
+
"templateResolver.errors.patch.blockRemoved": "The block {blockId} was already removed by an earlier step.",
|
|
74
|
+
"templateResolver.errors.patch.textNotFound": "The text {find} was not found in the block.",
|
|
75
|
+
"templateResolver.errors.patch.textAmbiguous": "The text {find} occurs {count} times in the block; use a longer text.",
|
|
76
|
+
"templateResolver.errors.patch.blockNotAllowed": "The block type {type} is not available in {kind} templates.",
|
|
77
|
+
"templateResolver.errors.patch.blockTypeMismatch": "This step needs a {expected} block, but the block is a {actual}.",
|
|
78
|
+
"templateResolver.errors.patch.invalidResourceKey": "The image key {resource} is not valid.",
|
|
79
|
+
"templateResolver.errors.patch.invalidButtonHref": "A button target must be a placeholder in double curly braces.",
|
|
80
|
+
"templateResolver.errors.patch.invalidVariableName": "The variable name {name} is not valid.",
|
|
81
|
+
"templateResolver.errors.patch.invalidVariableDefinition": "The definition of the variable {name} is not valid.",
|
|
82
|
+
"templateResolver.errors.patch.invalidDocument": "The change would produce an invalid document.",
|
|
83
|
+
"templateResolver.errors.patch.invalidMetaKey": "The meta key {key} is not allowed.",
|
|
84
|
+
"templateResolver.errors.patch.variablesDeclaredByFeature": "The variables of {slug} are fixed by the application and cannot be changed.",
|
|
85
|
+
"templateResolver.errors.patch.requiredPlaceholderRemoved": "The change removes required placeholders: {names}",
|
|
69
86
|
"templateResolver.errors.testMail.noChannel": "No email channel is set up, so no test mail can be sent.",
|
|
70
87
|
"templateResolver.errors.testMail.noAddress": "Your account has no email address to send the test mail to.",
|
|
71
88
|
"templateResolver.errors.testMail.failed": "The test mail could not be sent.",
|
|
@@ -77,6 +94,7 @@ export const defaultTranslations = {
|
|
|
77
94
|
"templateResolver.errors.noSystemTemplate": "There is no active system template to reset to.",
|
|
78
95
|
"templateResolver.errors.noDraft": "There is no draft to discard.",
|
|
79
96
|
"templateResolver.errors.systemOnlyTemplate": "Only the platform maintains this template; it cannot be overridden per tenant.",
|
|
97
|
+
"templateResolver.errors.templateNotTenantEditable": "Only the platform may edit this template.",
|
|
80
98
|
"templateResolver.errors.template.invalidMeta": "The template settings are invalid.",
|
|
81
99
|
"templateResolver.errors.template.meta.subject.required": "The subject is missing.",
|
|
82
100
|
"templateResolver.errors.template.meta.subject.invalid": "The subject is invalid (at most 200 characters, no line breaks).",
|
|
@@ -4,16 +4,16 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
4
4
|
// Single-line editor for plain-text fields that carry {{placeholders}}
|
|
5
5
|
// (subject, preheader). The stored value stays plain text; placeholders show
|
|
6
6
|
// as chips while editing. Lives in the same lazy chunk as the document editor.
|
|
7
|
-
import { cn } from "@cosmicdrift/kumiko-renderer
|
|
7
|
+
import { cn } from "@cosmicdrift/kumiko-renderer/web";
|
|
8
8
|
import { Extension, Node } from "@tiptap/core";
|
|
9
9
|
import { Placeholder, UndoRedo } from "@tiptap/extensions";
|
|
10
10
|
import { EditorContent, useEditor } from "@tiptap/react";
|
|
11
11
|
import StarterKit from "@tiptap/starter-kit";
|
|
12
12
|
import { useMemo, useState } from "react";
|
|
13
13
|
import { DocumentVariable } from "../document-schema.js";
|
|
14
|
+
import { contentToLine, lineToContent, singleLine } from "../placeholder-text.js";
|
|
14
15
|
import { createVariableView } from "./document-editor-extensions.js";
|
|
15
16
|
import { createEditorHandle } from "./editor-handle.js";
|
|
16
|
-
import { contentToLine, lineToContent, singleLine } from "./placeholder-text.js";
|
|
17
17
|
import { useStableByKey } from "./use-stable-by-key.js";
|
|
18
18
|
const LineDocument = Node.create({ name: "doc", topNode: true, content: "paragraph" });
|
|
19
19
|
// One line only: Enter must not split the paragraph.
|
|
@@ -21,7 +21,7 @@ export declare const tenantInvitationEntity: import("@cosmicdrift/kumiko-types/f
|
|
|
21
21
|
readonly sensitive?: boolean;
|
|
22
22
|
readonly writeOnly?: boolean;
|
|
23
23
|
readonly readAsInstruction?: boolean;
|
|
24
|
-
readonly format?: "email" | "url" | "phone" | "password";
|
|
24
|
+
readonly format?: "email" | "url" | "phone" | "password" | "month";
|
|
25
25
|
readonly default?: string;
|
|
26
26
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
27
27
|
readonly multiline?: boolean | {
|
|
@@ -44,7 +44,7 @@ export declare const tenantInvitationEntity: import("@cosmicdrift/kumiko-types/f
|
|
|
44
44
|
readonly sensitive?: boolean;
|
|
45
45
|
readonly writeOnly?: boolean;
|
|
46
46
|
readonly readAsInstruction?: boolean;
|
|
47
|
-
readonly format?: "email" | "url" | "phone" | "password";
|
|
47
|
+
readonly format?: "email" | "url" | "phone" | "password" | "month";
|
|
48
48
|
readonly default?: string;
|
|
49
49
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
50
50
|
readonly multiline?: boolean | {
|
|
@@ -92,7 +92,7 @@ export declare const tenantInvitationEntity: import("@cosmicdrift/kumiko-types/f
|
|
|
92
92
|
readonly sensitive?: boolean;
|
|
93
93
|
readonly writeOnly?: boolean;
|
|
94
94
|
readonly readAsInstruction?: boolean;
|
|
95
|
-
readonly format?: "email" | "url" | "phone" | "password";
|
|
95
|
+
readonly format?: "email" | "url" | "phone" | "password" | "month";
|
|
96
96
|
readonly default?: string;
|
|
97
97
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
98
98
|
readonly multiline?: boolean | {
|
|
@@ -151,7 +151,7 @@ export declare const tenantInvitationsTable: import("@cosmicdrift/kumiko-framewo
|
|
|
151
151
|
readonly sensitive?: boolean;
|
|
152
152
|
readonly writeOnly?: boolean;
|
|
153
153
|
readonly readAsInstruction?: boolean;
|
|
154
|
-
readonly format?: "email" | "url" | "phone" | "password";
|
|
154
|
+
readonly format?: "email" | "url" | "phone" | "password" | "month";
|
|
155
155
|
readonly default?: string;
|
|
156
156
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
157
157
|
readonly multiline?: boolean | {
|
|
@@ -174,7 +174,7 @@ export declare const tenantInvitationsTable: import("@cosmicdrift/kumiko-framewo
|
|
|
174
174
|
readonly sensitive?: boolean;
|
|
175
175
|
readonly writeOnly?: boolean;
|
|
176
176
|
readonly readAsInstruction?: boolean;
|
|
177
|
-
readonly format?: "email" | "url" | "phone" | "password";
|
|
177
|
+
readonly format?: "email" | "url" | "phone" | "password" | "month";
|
|
178
178
|
readonly default?: string;
|
|
179
179
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
180
180
|
readonly multiline?: boolean | {
|
|
@@ -222,7 +222,7 @@ export declare const tenantInvitationsTable: import("@cosmicdrift/kumiko-framewo
|
|
|
222
222
|
readonly sensitive?: boolean;
|
|
223
223
|
readonly writeOnly?: boolean;
|
|
224
224
|
readonly readAsInstruction?: boolean;
|
|
225
|
-
readonly format?: "email" | "url" | "phone" | "password";
|
|
225
|
+
readonly format?: "email" | "url" | "phone" | "password" | "month";
|
|
226
226
|
readonly default?: string;
|
|
227
227
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
228
228
|
readonly multiline?: boolean | {
|
|
@@ -13,7 +13,7 @@ export declare const tenantMembershipEntity: import("@cosmicdrift/kumiko-types/f
|
|
|
13
13
|
readonly sensitive?: boolean;
|
|
14
14
|
readonly writeOnly?: boolean;
|
|
15
15
|
readonly readAsInstruction?: boolean;
|
|
16
|
-
readonly format?: "email" | "url" | "phone" | "password";
|
|
16
|
+
readonly format?: "email" | "url" | "phone" | "password" | "month";
|
|
17
17
|
readonly default?: string;
|
|
18
18
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
19
19
|
readonly multiline?: boolean | {
|
|
@@ -36,7 +36,7 @@ export declare const tenantMembershipEntity: import("@cosmicdrift/kumiko-types/f
|
|
|
36
36
|
readonly sensitive?: boolean;
|
|
37
37
|
readonly writeOnly?: boolean;
|
|
38
38
|
readonly readAsInstruction?: boolean;
|
|
39
|
-
readonly format?: "email" | "url" | "phone" | "password";
|
|
39
|
+
readonly format?: "email" | "url" | "phone" | "password" | "month";
|
|
40
40
|
readonly default?: string;
|
|
41
41
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
42
42
|
readonly multiline?: boolean | {
|
|
@@ -61,7 +61,7 @@ export declare const tenantMembershipsTable: import("@cosmicdrift/kumiko-framewo
|
|
|
61
61
|
readonly sensitive?: boolean;
|
|
62
62
|
readonly writeOnly?: boolean;
|
|
63
63
|
readonly readAsInstruction?: boolean;
|
|
64
|
-
readonly format?: "email" | "url" | "phone" | "password";
|
|
64
|
+
readonly format?: "email" | "url" | "phone" | "password" | "month";
|
|
65
65
|
readonly default?: string;
|
|
66
66
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
67
67
|
readonly multiline?: boolean | {
|
|
@@ -84,7 +84,7 @@ export declare const tenantMembershipsTable: import("@cosmicdrift/kumiko-framewo
|
|
|
84
84
|
readonly sensitive?: boolean;
|
|
85
85
|
readonly writeOnly?: boolean;
|
|
86
86
|
readonly readAsInstruction?: boolean;
|
|
87
|
-
readonly format?: "email" | "url" | "phone" | "password";
|
|
87
|
+
readonly format?: "email" | "url" | "phone" | "password" | "month";
|
|
88
88
|
readonly default?: string;
|
|
89
89
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
90
90
|
readonly multiline?: boolean | {
|
|
@@ -15,7 +15,7 @@ export declare const tenantEntity: import("@cosmicdrift/kumiko-types/fields").En
|
|
|
15
15
|
readonly sensitive?: boolean;
|
|
16
16
|
readonly writeOnly?: boolean;
|
|
17
17
|
readonly readAsInstruction?: boolean;
|
|
18
|
-
readonly format?: "email" | "url" | "phone" | "password";
|
|
18
|
+
readonly format?: "email" | "url" | "phone" | "password" | "month";
|
|
19
19
|
readonly default?: string;
|
|
20
20
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
21
21
|
readonly multiline?: boolean | {
|
|
@@ -38,7 +38,7 @@ export declare const tenantEntity: import("@cosmicdrift/kumiko-types/fields").En
|
|
|
38
38
|
readonly sensitive?: boolean;
|
|
39
39
|
readonly writeOnly?: boolean;
|
|
40
40
|
readonly readAsInstruction?: boolean;
|
|
41
|
-
readonly format?: "email" | "url" | "phone" | "password";
|
|
41
|
+
readonly format?: "email" | "url" | "phone" | "password" | "month";
|
|
42
42
|
readonly default?: string;
|
|
43
43
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
44
44
|
readonly multiline?: boolean | {
|
|
@@ -105,7 +105,7 @@ export declare const tenantEntity: import("@cosmicdrift/kumiko-types/fields").En
|
|
|
105
105
|
readonly sensitive?: boolean;
|
|
106
106
|
readonly writeOnly?: boolean;
|
|
107
107
|
readonly readAsInstruction?: boolean;
|
|
108
|
-
readonly format?: "email" | "url" | "phone" | "password";
|
|
108
|
+
readonly format?: "email" | "url" | "phone" | "password" | "month";
|
|
109
109
|
readonly default?: string;
|
|
110
110
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
111
111
|
readonly multiline?: boolean | {
|
|
@@ -175,7 +175,7 @@ export declare const tenantTable: import("@cosmicdrift/kumiko-framework/db").Ent
|
|
|
175
175
|
readonly sensitive?: boolean;
|
|
176
176
|
readonly writeOnly?: boolean;
|
|
177
177
|
readonly readAsInstruction?: boolean;
|
|
178
|
-
readonly format?: "email" | "url" | "phone" | "password";
|
|
178
|
+
readonly format?: "email" | "url" | "phone" | "password" | "month";
|
|
179
179
|
readonly default?: string;
|
|
180
180
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
181
181
|
readonly multiline?: boolean | {
|
|
@@ -198,7 +198,7 @@ export declare const tenantTable: import("@cosmicdrift/kumiko-framework/db").Ent
|
|
|
198
198
|
readonly sensitive?: boolean;
|
|
199
199
|
readonly writeOnly?: boolean;
|
|
200
200
|
readonly readAsInstruction?: boolean;
|
|
201
|
-
readonly format?: "email" | "url" | "phone" | "password";
|
|
201
|
+
readonly format?: "email" | "url" | "phone" | "password" | "month";
|
|
202
202
|
readonly default?: string;
|
|
203
203
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
204
204
|
readonly multiline?: boolean | {
|
|
@@ -265,7 +265,7 @@ export declare const tenantTable: import("@cosmicdrift/kumiko-framework/db").Ent
|
|
|
265
265
|
readonly sensitive?: boolean;
|
|
266
266
|
readonly writeOnly?: boolean;
|
|
267
267
|
readonly readAsInstruction?: boolean;
|
|
268
|
-
readonly format?: "email" | "url" | "phone" | "password";
|
|
268
|
+
readonly format?: "email" | "url" | "phone" | "password" | "month";
|
|
269
269
|
readonly default?: string;
|
|
270
270
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
271
271
|
readonly multiline?: boolean | {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type TranslationsByLocale } from "@cosmicdrift/kumiko-renderer";
|
|
2
|
-
import type { ClientFeatureDefinition } from "@cosmicdrift/kumiko-renderer
|
|
2
|
+
import type { ClientFeatureDefinition } from "@cosmicdrift/kumiko-renderer/web";
|
|
3
3
|
export type TenantClientOptions = {
|
|
4
4
|
readonly translations?: TranslationsByLocale;
|
|
5
5
|
};
|
|
@@ -5,7 +5,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
5
5
|
// screens.ts). The list frame itself is the generic declarative
|
|
6
6
|
// projectionList renderer — only this one cell stays TSX.
|
|
7
7
|
import { useTranslation } from "@cosmicdrift/kumiko-renderer";
|
|
8
|
-
import { StatusBadge } from "@cosmicdrift/kumiko-renderer
|
|
8
|
+
import { StatusBadge } from "@cosmicdrift/kumiko-renderer/web";
|
|
9
9
|
import { translateOrRaw } from "../../shared/web/translate-or-raw.js";
|
|
10
10
|
const STATUS_TONE = {
|
|
11
11
|
active: "ok",
|
|
@@ -14,7 +14,7 @@ export declare const tierAssignmentEntity: import("@cosmicdrift/kumiko-types/fie
|
|
|
14
14
|
readonly sensitive?: boolean;
|
|
15
15
|
readonly writeOnly?: boolean;
|
|
16
16
|
readonly readAsInstruction?: boolean;
|
|
17
|
-
readonly format?: "email" | "url" | "phone" | "password";
|
|
17
|
+
readonly format?: "email" | "url" | "phone" | "password" | "month";
|
|
18
18
|
readonly default?: string;
|
|
19
19
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
20
20
|
readonly multiline?: boolean | {
|
|
@@ -21,7 +21,7 @@ export declare function createTierResolver<TTier extends string, TCaps>(deps: Ti
|
|
|
21
21
|
readonly sensitive?: boolean;
|
|
22
22
|
readonly writeOnly?: boolean;
|
|
23
23
|
readonly readAsInstruction?: boolean;
|
|
24
|
-
readonly format?: "email" | "url" | "phone" | "password";
|
|
24
|
+
readonly format?: "email" | "url" | "phone" | "password" | "month";
|
|
25
25
|
readonly default?: string;
|
|
26
26
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
27
27
|
readonly multiline?: boolean | {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type TranslationsByLocale } from "@cosmicdrift/kumiko-renderer";
|
|
2
|
-
import type { ClientFeatureDefinition } from "@cosmicdrift/kumiko-renderer
|
|
2
|
+
import type { ClientFeatureDefinition } from "@cosmicdrift/kumiko-renderer/web";
|
|
3
3
|
export type TierEngineClientOptions = {
|
|
4
4
|
/** Per-key overrides over the default bundles (de/en). */
|
|
5
5
|
readonly translations?: TranslationsByLocale;
|