@cosmicdrift/kumiko-samples 0.377.0 → 0.379.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/package.json +1 -1
- package/packages/bundled-features/package.json +18 -17
- package/packages/bundled-features/src/account-security/feature.ts +2 -2
- package/packages/bundled-features/src/account-security/index.ts +8 -8
- package/packages/bundled-features/src/account-security/{constants.ts → web/constants.ts} +0 -2
- package/packages/bundled-features/src/account-security/{i18n.ts → web/i18n.ts} +0 -1
- package/packages/bundled-features/src/admin-shell/feature.ts +10 -9
- package/packages/bundled-features/src/admin-shell/index.ts +8 -8
- package/packages/bundled-features/src/admin-shell/web/client-plugin.tsx +2 -3
- package/packages/bundled-features/src/admin-shell/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/admin-shell/web/default-translations.ts +10 -0
- package/packages/bundled-features/src/admin-shell/web/i18n.ts +51 -9
- package/packages/bundled-features/src/admin-shell/web/index.ts +0 -1
- package/packages/bundled-features/src/audit/changes.json +7 -0
- package/packages/bundled-features/src/audit/feature.ts +72 -64
- package/packages/bundled-features/src/audit/handlers/audit-events.ts +153 -0
- package/packages/bundled-features/src/audit/handlers/audit-system-db.ts +13 -0
- package/packages/bundled-features/src/audit/handlers/details-all-tenants.query.ts +26 -0
- package/packages/bundled-features/src/audit/handlers/details.query.ts +11 -39
- package/packages/bundled-features/src/audit/handlers/list-all-tenants.query.ts +47 -0
- package/packages/bundled-features/src/audit/handlers/list.query.ts +16 -123
- package/packages/bundled-features/src/audit/handlers/resolve-audit-tenant.ts +21 -7
- package/packages/bundled-features/src/audit/index.ts +1 -1
- package/packages/bundled-features/src/audit/run-escape-hatch-retention.ts +4 -4
- package/packages/bundled-features/src/audit/screens.ts +82 -0
- package/packages/bundled-features/src/audit/web/client-plugin.tsx +2 -3
- package/packages/bundled-features/src/audit/{constants.ts → web/constants.ts} +11 -1
- package/packages/bundled-features/src/audit/web/default-translations.ts +7 -0
- package/packages/bundled-features/src/audit/web/i18n.ts +33 -7
- package/packages/bundled-features/src/audit/web/index.ts +0 -2
- package/packages/bundled-features/src/auth-email-password/bootstrap.ts +6 -6
- package/packages/bundled-features/src/auth-email-password/changes.json +6 -0
- package/packages/bundled-features/src/auth-email-password/errors.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/feature.ts +2 -2
- package/packages/bundled-features/src/auth-email-password/handlers/confirm-account-unlock.write.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/invite-accept-with-login.write.ts +4 -4
- package/packages/bundled-features/src/auth-email-password/handlers/invite-create.write.ts +3 -3
- package/packages/bundled-features/src/auth-email-password/handlers/invite-info.query.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/login.write.ts +38 -4
- package/packages/bundled-features/src/auth-email-password/handlers/request-account-unlock.write.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/request-email-verification.write.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/request-password-reset.write.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/reset-password.write.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/verify-email.write.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/index.ts +6 -1
- package/packages/bundled-features/src/auth-email-password/mail-notifications.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/signup-activation.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/web/auth-client.ts +0 -1
- package/packages/bundled-features/src/auth-email-password/web/auth-form-logic.ts +0 -1
- package/packages/bundled-features/src/auth-email-password/web/auth-form-primitives.tsx +0 -1
- package/packages/bundled-features/src/auth-email-password/web/auth-gate.tsx +0 -1
- package/packages/bundled-features/src/auth-email-password/web/auth-redirect.ts +0 -1
- package/packages/bundled-features/src/auth-email-password/web/client-actions.ts +0 -1
- package/packages/bundled-features/src/auth-email-password/web/client-plugin.ts +1 -2
- package/packages/bundled-features/src/auth-email-password/web/confirm-account-unlock-screen.tsx +0 -1
- package/packages/bundled-features/src/auth-email-password/{constants.ts → web/constants.ts} +3 -6
- package/packages/bundled-features/src/auth-email-password/web/default-topbar-actions.tsx +0 -1
- package/packages/bundled-features/src/auth-email-password/web/forgot-password-screen.tsx +0 -1
- package/packages/bundled-features/src/auth-email-password/{i18n.ts → web/i18n.ts} +3 -4
- package/packages/bundled-features/src/auth-email-password/web/index.ts +1 -2
- package/packages/bundled-features/src/auth-email-password/web/invite-accept-screen.tsx +2 -3
- package/packages/bundled-features/src/auth-email-password/web/login-screen.tsx +0 -1
- package/packages/bundled-features/src/auth-email-password/{mail-i18n.ts → web/mail-i18n.ts} +0 -1
- package/packages/bundled-features/src/auth-email-password/web/request-account-unlock-screen.tsx +0 -1
- package/packages/bundled-features/src/auth-email-password/web/reset-password-screen.tsx +0 -1
- package/packages/bundled-features/src/auth-email-password/web/session-bootstrap-error.tsx +0 -1
- package/packages/bundled-features/src/auth-email-password/web/session.tsx +0 -1
- package/packages/bundled-features/src/auth-email-password/web/signup-complete-screen.tsx +2 -3
- package/packages/bundled-features/src/auth-email-password/web/signup-screen.tsx +0 -1
- package/packages/bundled-features/src/auth-email-password/web/tenant-menu-items.tsx +0 -1
- package/packages/bundled-features/src/auth-email-password/web/tenant-switcher.tsx +0 -1
- package/packages/bundled-features/src/auth-email-password/web/use-shell-user.ts +0 -1
- package/packages/bundled-features/src/auth-email-password/web/user-menu.tsx +0 -1
- package/packages/bundled-features/src/auth-email-password/web/verify-email-screen.tsx +0 -1
- package/packages/bundled-features/src/auth-mfa/changes.json +6 -0
- package/packages/bundled-features/src/auth-mfa/errors.ts +2 -2
- package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm-preauth.write.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/handlers/enable-start-preauth.write.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/handlers/enable-start.write.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/handlers/verify.write.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/index.ts +8 -8
- package/packages/bundled-features/src/auth-mfa/mfa-status-checker.ts +4 -4
- package/packages/bundled-features/src/auth-mfa/screens.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/web/client-plugin.ts +0 -1
- package/packages/bundled-features/src/auth-mfa/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/auth-mfa/web/i18n.ts +0 -1
- package/packages/bundled-features/src/auth-mfa/web/index.ts +0 -1
- package/packages/bundled-features/src/auth-mfa/web/mfa-client.ts +0 -1
- package/packages/bundled-features/src/auth-mfa/web/mfa-disable-dialog.tsx +1 -2
- package/packages/bundled-features/src/auth-mfa/web/mfa-recovery-codes-reveal.tsx +0 -1
- package/packages/bundled-features/src/auth-mfa/web/mfa-regenerate-recovery-dialog.tsx +1 -2
- package/packages/bundled-features/src/auth-mfa/web/mfa-setup-preauth-screen.tsx +21 -23
- package/packages/bundled-features/src/auth-mfa/web/mfa-verify-screen.tsx +0 -1
- package/packages/bundled-features/src/billing-foundation/changes.json +18 -0
- package/packages/bundled-features/src/billing-foundation/checkout-core.ts +3 -3
- package/packages/bundled-features/src/billing-foundation/consumer-protection/consent-text.ts +2 -2
- package/packages/bundled-features/src/billing-foundation/consumer-protection/issue-confirmation.ts +11 -3
- package/packages/bundled-features/src/billing-foundation/consumer-protection/mail-notifications.ts +11 -1
- package/packages/bundled-features/src/billing-foundation/consumer-protection/register-consent.ts +1 -1
- package/packages/bundled-features/src/billing-foundation/consumer-protection/register-termination.ts +12 -1
- package/packages/bundled-features/src/billing-foundation/consumer-protection/stored-user-email.ts +12 -0
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-mail.ts +6 -1
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-notify.ts +1 -1
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-pages.ts +167 -28
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-record.ts +102 -3
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-request.ts +43 -12
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-revoke.ts +202 -0
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-texts.ts +70 -0
- package/packages/bundled-features/src/billing-foundation/events.ts +20 -2
- package/packages/bundled-features/src/billing-foundation/feature.ts +5 -5
- package/packages/bundled-features/src/billing-foundation/handlers/process-event.write.ts +82 -9
- package/packages/bundled-features/src/billing-foundation/handlers/switch-plan.write.ts +1 -1
- package/packages/bundled-features/src/billing-foundation/handlers/sync-subscription.write.ts +1 -1
- package/packages/bundled-features/src/billing-foundation/index.ts +27 -27
- package/packages/bundled-features/src/billing-foundation/plan-catalog.ts +7 -7
- package/packages/bundled-features/src/billing-foundation/screens.ts +1 -1
- package/packages/bundled-features/src/billing-foundation/subscription-tier-sync.ts +1 -1
- package/packages/bundled-features/src/billing-foundation/types.ts +17 -3
- package/packages/bundled-features/src/billing-foundation/validate-options.ts +3 -3
- package/packages/bundled-features/src/billing-foundation/web/billing-contact-plan.tsx +1 -3
- package/packages/bundled-features/src/billing-foundation/web/billing-plans-panel.tsx +5 -7
- package/packages/bundled-features/src/billing-foundation/web/cancel-contract-dialog.tsx +1 -3
- package/packages/bundled-features/src/billing-foundation/web/checkout-consent-dialog.tsx +1 -3
- package/packages/bundled-features/src/billing-foundation/web/client-plugin.tsx +1 -2
- package/packages/bundled-features/src/billing-foundation/{constants.ts → web/constants.ts} +37 -31
- package/packages/bundled-features/src/billing-foundation/{consumer-protection → web/consumer-protection}/consent-locale.ts +0 -1
- package/packages/bundled-features/src/billing-foundation/{contact-card.ts → web/contact-card.ts} +0 -2
- package/packages/bundled-features/src/billing-foundation/web/index.ts +14 -15
- package/packages/bundled-features/src/billing-foundation/web/localized-params.ts +0 -2
- package/packages/bundled-features/src/billing-foundation/webhook-handler.ts +5 -2
- package/packages/bundled-features/src/cap-counter/changes.json +12 -0
- package/packages/bundled-features/src/cap-counter/stock-cap-guard.ts +9 -0
- package/packages/bundled-features/src/cap-overview/feature.ts +1 -1
- package/packages/bundled-features/src/cap-overview/handlers/caps-usage.query.ts +1 -1
- package/packages/bundled-features/src/cap-overview/handlers/tenant-caps-list.query.ts +2 -2
- package/packages/bundled-features/src/cap-overview/index.ts +9 -9
- package/packages/bundled-features/src/cap-overview/screens.ts +2 -2
- package/packages/bundled-features/src/cap-overview/web/cap-cards-panel.tsx +1 -2
- package/packages/bundled-features/src/cap-overview/web/cap-usage-bar.tsx +1 -2
- package/packages/bundled-features/src/cap-overview/web/cap-usage-cell.tsx +0 -2
- package/packages/bundled-features/src/cap-overview/web/client-plugin.tsx +3 -4
- package/packages/bundled-features/src/cap-overview/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/cap-overview/web/index.ts +0 -1
- package/packages/bundled-features/src/cap-overview/{usage-math.ts → web/usage-math.ts} +1 -2
- package/packages/bundled-features/src/compliance-profiles/feature.ts +5 -5
- package/packages/bundled-features/src/compliance-profiles/index.ts +6 -6
- package/packages/bundled-features/src/compliance-profiles/web/client-plugin.tsx +2 -3
- package/packages/bundled-features/src/compliance-profiles/web/compliance-profile-catalog.tsx +1 -2
- package/packages/bundled-features/src/compliance-profiles/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/compliance-profiles/web/i18n.ts +0 -1
- package/packages/bundled-features/src/compliance-profiles/web/index.ts +0 -1
- package/packages/bundled-features/src/config/index.ts +6 -6
- package/packages/bundled-features/src/config/web/client-plugin.ts +1 -2
- package/packages/bundled-features/src/config/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/config/web/i18n.ts +1 -1
- package/packages/bundled-features/src/config/web/index.ts +1 -3
- package/packages/bundled-features/src/config/write-helpers.ts +1 -1
- package/packages/bundled-features/src/custom-fields/feature.ts +8 -8
- package/packages/bundled-features/src/custom-fields/handlers/clear-custom-field.write.ts +1 -1
- package/packages/bundled-features/src/custom-fields/handlers/define-tenant-field.write.ts +1 -1
- package/packages/bundled-features/src/custom-fields/handlers/delete-system-field.write.ts +1 -1
- package/packages/bundled-features/src/custom-fields/handlers/delete-tenant-field.write.ts +4 -4
- package/packages/bundled-features/src/custom-fields/handlers/set-custom-field.write.ts +1 -1
- package/packages/bundled-features/src/custom-fields/handlers/update-tenant-field.write.ts +1 -1
- package/packages/bundled-features/src/custom-fields/index.ts +8 -8
- package/packages/bundled-features/src/custom-fields/lib/value-schema.ts +1 -1
- package/packages/bundled-features/src/custom-fields/schemas.ts +1 -1
- package/packages/bundled-features/src/custom-fields/web/client-plugin.tsx +1 -2
- package/packages/bundled-features/src/custom-fields/{constants.ts → web/constants.ts} +18 -19
- package/packages/bundled-features/src/custom-fields/web/custom-fields-form-section.tsx +1 -2
- package/packages/bundled-features/src/custom-fields/web/i18n.ts +0 -1
- package/packages/bundled-features/src/custom-fields/web/index.ts +2 -3
- package/packages/bundled-features/src/custom-fields/wire-for-entity.ts +1 -2
- package/packages/bundled-features/src/delivery/address-opt-out.ts +1 -1
- package/packages/bundled-features/src/delivery/attempt-log-retention.ts +24 -8
- package/packages/bundled-features/src/delivery/changes.json +6 -0
- package/packages/bundled-features/src/delivery/constants.ts +2 -2
- package/packages/bundled-features/src/delivery/i18n.ts +1 -1
- package/packages/bundled-features/src/delivery/unsubscribe-page.ts +1 -1
- package/packages/bundled-features/src/delivery/web/client-plugin.tsx +6 -7
- package/packages/bundled-features/src/delivery/web/delivery-channel-cell.tsx +0 -1
- package/packages/bundled-features/src/delivery/web/delivery-error-cell.tsx +0 -1
- package/packages/bundled-features/src/delivery/web/delivery-status-cell.tsx +1 -2
- package/packages/bundled-features/src/delivery/web/delivery-time-cell.tsx +0 -1
- package/packages/bundled-features/src/delivery/web/delivery-type-cell.tsx +0 -1
- package/packages/bundled-features/src/delivery/web/index.ts +0 -1
- package/packages/bundled-features/src/delivery/{public-names.ts → web/public-names.ts} +0 -1
- package/packages/bundled-features/src/document-ingest-foundation/changes.json +6 -0
- package/packages/bundled-features/src/document-ingest-foundation/events.ts +4 -0
- package/packages/bundled-features/src/document-ingest-foundation/executor.ts +2 -1
- package/packages/bundled-features/src/document-ingest-foundation/feature.ts +18 -4
- package/packages/bundled-features/src/document-ingest-foundation/index.ts +1 -0
- package/packages/bundled-features/src/feature-toggles/feature.ts +7 -7
- package/packages/bundled-features/src/feature-toggles/handlers/list.query.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/handlers/registered.query.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/handlers/set.write.ts +3 -3
- package/packages/bundled-features/src/feature-toggles/index.ts +6 -6
- package/packages/bundled-features/src/feature-toggles/web/client-plugin.tsx +1 -2
- package/packages/bundled-features/src/feature-toggles/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/feature-toggles/web/i18n.ts +0 -1
- package/packages/bundled-features/src/feature-toggles/web/index.ts +0 -1
- package/packages/bundled-features/src/files/changes.json +7 -0
- package/packages/bundled-features/src/folders/feature.ts +1 -1
- package/packages/bundled-features/src/folders/handlers/clear-folder.write.ts +1 -1
- package/packages/bundled-features/src/folders/handlers/delete-folder.write.ts +1 -1
- package/packages/bundled-features/src/folders/handlers/set-folder.write.ts +1 -1
- package/packages/bundled-features/src/folders/index.ts +8 -8
- package/packages/bundled-features/src/folders/web/client-plugin.tsx +1 -3
- package/packages/bundled-features/src/folders/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/folders/web/folder-manager.tsx +1 -2
- package/packages/bundled-features/src/folders/web/folder-section.tsx +1 -2
- package/packages/bundled-features/src/folders/web/i18n.ts +0 -1
- package/packages/bundled-features/src/folders/web/index.ts +1 -2
- package/packages/bundled-features/src/folders/web/tree.ts +0 -1
- package/packages/bundled-features/src/form-draft/changes.json +7 -0
- package/packages/bundled-features/src/form-draft/db/queries/cleanup.ts +25 -11
- package/packages/bundled-features/src/form-draft/decrypt-draft.ts +24 -0
- package/packages/bundled-features/src/form-draft/entity.ts +6 -9
- package/packages/bundled-features/src/form-draft/feature.ts +1 -1
- package/packages/bundled-features/src/form-draft/handlers/cleanup.job.ts +26 -5
- package/packages/bundled-features/src/form-draft/handlers/discard.write.ts +1 -1
- package/packages/bundled-features/src/form-draft/handlers/get.query.ts +6 -7
- package/packages/bundled-features/src/form-draft/handlers/list.query.ts +13 -7
- package/packages/bundled-features/src/form-draft/handlers/save.write.ts +5 -5
- package/packages/bundled-features/src/form-draft/index.ts +8 -8
- package/packages/bundled-features/src/form-draft/lookup.ts +10 -4
- package/packages/bundled-features/src/form-draft/schemas.ts +1 -1
- package/packages/bundled-features/src/form-draft/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/form-draft-user-data/hooks.ts +2 -2
- package/packages/bundled-features/src/inbound-mail-foundation/changes.json +6 -0
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-accounts.query.ts +11 -4
- package/packages/bundled-features/src/inbound-mail-foundation/retention-sweep.ts +10 -10
- package/packages/bundled-features/src/jobs/feature.ts +7 -7
- package/packages/bundled-features/src/jobs/handlers/retry.write.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/trigger.write.ts +1 -1
- package/packages/bundled-features/src/jobs/index.ts +1 -1
- package/packages/bundled-features/src/jobs/web/client-plugin.tsx +2 -3
- package/packages/bundled-features/src/jobs/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/jobs/web/default-translations.ts +7 -0
- package/packages/bundled-features/src/jobs/web/i18n.ts +53 -7
- package/packages/bundled-features/src/jobs/web/index.ts +0 -1
- package/packages/bundled-features/src/ledger/changes.json +7 -0
- package/packages/bundled-features/src/ledger/entity.ts +1 -1
- package/packages/bundled-features/src/ledger/feature.ts +1 -1
- package/packages/bundled-features/src/ledger/handlers/confirm-schedule-period.write.ts +2 -10
- package/packages/bundled-features/src/ledger/handlers/create-transaction.write.ts +1 -1
- package/packages/bundled-features/src/ledger/handlers/reports.query.ts +1 -1
- package/packages/bundled-features/src/ledger/handlers/reverse-transaction.write.ts +1 -1
- package/packages/bundled-features/src/ledger/index.ts +13 -13
- package/packages/bundled-features/src/ledger/recurring.ts +1 -1
- package/packages/bundled-features/src/ledger/reports.ts +1 -1
- package/packages/bundled-features/src/ledger/schemas.ts +1 -1
- package/packages/bundled-features/src/ledger/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/ledger/web/index.ts +11 -12
- package/packages/bundled-features/src/legal-pages/README.md +1 -1
- package/packages/bundled-features/src/legal-pages/feature.ts +5 -5
- package/packages/bundled-features/src/legal-pages/index.ts +11 -11
- package/packages/bundled-features/src/legal-pages/lib/boot-check.ts +1 -1
- package/packages/bundled-features/src/legal-pages/lib/validate-routes.ts +1 -1
- package/packages/bundled-features/src/legal-pages/web/client-plugin.ts +1 -2
- package/packages/bundled-features/src/legal-pages/{constants.ts → web/constants.ts} +6 -8
- package/packages/bundled-features/src/legal-pages/web/index.ts +0 -1
- package/packages/bundled-features/src/mail-foundation/changes.json +6 -0
- package/packages/bundled-features/src/mail-foundation/i18n.ts +3 -2
- package/packages/bundled-features/src/mail-transport-smtp/i18n.ts +1 -1
- package/packages/bundled-features/src/managed-pages/feature.ts +1 -1
- package/packages/bundled-features/src/managed-pages/web/client-plugin.tsx +1 -2
- package/packages/bundled-features/src/managed-pages/web/default-translations.ts +17 -0
- package/packages/bundled-features/src/managed-pages/web/i18n.ts +59 -16
- package/packages/bundled-features/src/managed-pages/web/index.ts +1 -2
- package/packages/bundled-features/src/metrics/compute.ts +1 -1
- package/packages/bundled-features/src/metrics/feature.ts +6 -6
- package/packages/bundled-features/src/metrics/index.ts +8 -8
- package/packages/bundled-features/src/metrics/types.ts +1 -1
- package/packages/bundled-features/src/metrics/validate.ts +1 -1
- package/packages/bundled-features/src/metrics/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/metrics/window.ts +1 -1
- package/packages/bundled-features/src/notes-history/feature.ts +1 -1
- package/packages/bundled-features/src/notes-history/handlers/add-note.write.ts +1 -1
- package/packages/bundled-features/src/notes-history/index.ts +8 -8
- package/packages/bundled-features/src/notes-history/web/client-plugin.tsx +1 -3
- package/packages/bundled-features/src/notes-history/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/notes-history/web/i18n.ts +0 -1
- package/packages/bundled-features/src/notes-history/web/index.ts +2 -3
- package/packages/bundled-features/src/notes-history/web/notes-section.tsx +2 -3
- package/packages/bundled-features/src/personal-access-tokens/feature.ts +12 -10
- package/packages/bundled-features/src/personal-access-tokens/handlers/available-scopes.query.ts +1 -1
- package/packages/bundled-features/src/personal-access-tokens/handlers/create.write.ts +1 -1
- package/packages/bundled-features/src/personal-access-tokens/handlers/revoke.write.ts +1 -1
- package/packages/bundled-features/src/personal-access-tokens/hash.ts +1 -1
- package/packages/bundled-features/src/personal-access-tokens/i18n.ts +2 -2
- package/packages/bundled-features/src/personal-access-tokens/index.ts +5 -5
- package/packages/bundled-features/src/personal-access-tokens/resolver.ts +1 -1
- package/packages/bundled-features/src/personal-access-tokens/schema/api-token.ts +1 -1
- package/packages/bundled-features/src/personal-access-tokens/screens.ts +2 -2
- package/packages/bundled-features/src/personal-access-tokens/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/personal-access-tokens/{scopes.ts → web/scopes.ts} +0 -1
- package/packages/bundled-features/src/presets/changes.json +7 -0
- package/packages/bundled-features/src/presets/index.ts +0 -1
- package/packages/bundled-features/src/presets/security-baseline.ts +1 -1
- package/packages/bundled-features/src/renderer-foundation/types.ts +1 -1
- package/packages/bundled-features/src/secrets/feature.ts +1 -1
- package/packages/bundled-features/src/secrets/handlers/delete.write.ts +1 -1
- package/packages/bundled-features/src/secrets/handlers/list.query.ts +1 -1
- package/packages/bundled-features/src/secrets/handlers/set.write.ts +1 -1
- package/packages/bundled-features/src/secrets/i18n.ts +1 -1
- package/packages/bundled-features/src/secrets/index.ts +8 -8
- package/packages/bundled-features/src/secrets/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/secrets/write-gate.ts +1 -1
- package/packages/bundled-features/src/sessions/feature.ts +7 -4
- package/packages/bundled-features/src/sessions/{i18n.ts → web/i18n.ts} +0 -1
- package/packages/bundled-features/src/shared/index.ts +6 -1
- package/packages/bundled-features/src/shared/purge-files-reaching-subject.ts +10 -2
- package/packages/bundled-features/src/shared/web/translate-or-raw.ts +0 -1
- package/packages/bundled-features/src/subscription-stripe/feature.ts +2 -0
- package/packages/bundled-features/src/subscription-stripe/plugin-methods.ts +19 -0
- package/packages/bundled-features/src/subscription-stripe/verify-webhook.ts +1 -0
- package/packages/bundled-features/src/tags/changes.json +6 -0
- package/packages/bundled-features/src/tags/feature.ts +1 -1
- package/packages/bundled-features/src/tags/handlers/assign-tag.write.ts +11 -7
- package/packages/bundled-features/src/tags/handlers/create-tag.write.ts +1 -1
- package/packages/bundled-features/src/tags/handlers/delete-tag.write.ts +4 -1
- package/packages/bundled-features/src/tags/handlers/remove-tag.write.ts +1 -1
- package/packages/bundled-features/src/tags/handlers/update-tag.write.ts +1 -1
- package/packages/bundled-features/src/tags/index.ts +12 -12
- package/packages/bundled-features/src/tags/screens.ts +1 -1
- package/packages/bundled-features/src/tags/web/client-plugin.tsx +1 -3
- package/packages/bundled-features/src/tags/{constants.ts → web/constants.ts} +4 -1
- package/packages/bundled-features/src/tags/web/entity-tags.tsx +1 -2
- package/packages/bundled-features/src/tags/web/i18n.ts +2 -2
- package/packages/bundled-features/src/tags/web/index.ts +2 -3
- package/packages/bundled-features/src/tags/web/tag-chip.tsx +0 -1
- package/packages/bundled-features/src/tags/web/tag-filter.tsx +1 -2
- package/packages/bundled-features/src/tags/web/tag-manager.tsx +5 -4
- package/packages/bundled-features/src/tags/web/tag-picker.tsx +0 -1
- package/packages/bundled-features/src/tags/web/tag-section.tsx +1 -2
- package/packages/bundled-features/src/tags/web/tags-cell.tsx +1 -2
- package/packages/bundled-features/src/template-resolver/README.md +1 -1
- package/packages/bundled-features/src/template-resolver/api.ts +75 -28
- package/packages/bundled-features/src/template-resolver/changes.json +63 -0
- package/packages/bundled-features/src/template-resolver/compile-document-body.ts +62 -4
- package/packages/bundled-features/src/template-resolver/compile-steps-block.ts +2 -2
- package/packages/bundled-features/src/template-resolver/document-ops.ts +5 -5
- package/packages/bundled-features/src/template-resolver/document-sanitizer.ts +39 -4
- package/packages/bundled-features/src/template-resolver/feature.ts +88 -38
- package/packages/bundled-features/src/template-resolver/handlers/by-slug.query.ts +6 -1
- package/packages/bundled-features/src/template-resolver/handlers/by-tenant.query.ts +6 -2
- package/packages/bundled-features/src/template-resolver/handlers/collection-item.query.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/collection-list.query.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/collection-set.write.ts +20 -7
- package/packages/bundled-features/src/template-resolver/handlers/collection-shared.ts +0 -6
- package/packages/bundled-features/src/template-resolver/handlers/copy-locale.write.ts +69 -60
- package/packages/bundled-features/src/template-resolver/handlers/diff-to-system.query.ts +7 -1
- package/packages/bundled-features/src/template-resolver/handlers/discard-draft.write.ts +37 -14
- package/packages/bundled-features/src/template-resolver/handlers/document-base.ts +8 -2
- package/packages/bundled-features/src/template-resolver/handlers/document-blocks.query.ts +2 -2
- package/packages/bundled-features/src/template-resolver/handlers/export-bundle.query.ts +5 -2
- package/packages/bundled-features/src/template-resolver/handlers/find-by-id.query.ts +4 -2
- package/packages/bundled-features/src/template-resolver/handlers/import-bundle.write.ts +37 -28
- package/packages/bundled-features/src/template-resolver/handlers/layout-source.query.ts +10 -5
- package/packages/bundled-features/src/template-resolver/handlers/list.query.ts +5 -2
- package/packages/bundled-features/src/template-resolver/handlers/overview.query.ts +132 -70
- package/packages/bundled-features/src/template-resolver/handlers/patch-draft.write.ts +106 -97
- package/packages/bundled-features/src/template-resolver/handlers/reset-to-system.write.ts +62 -49
- package/packages/bundled-features/src/template-resolver/handlers/resource-link-pdf.write.ts +44 -29
- package/packages/bundled-features/src/template-resolver/handlers/resource-remove.write.ts +52 -36
- package/packages/bundled-features/src/template-resolver/handlers/resource-shared.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/resource-upload.write.ts +127 -107
- package/packages/bundled-features/src/template-resolver/handlers/send-test-shared.ts +38 -0
- package/packages/bundled-features/src/template-resolver/handlers/send-test-status.query.ts +31 -0
- package/packages/bundled-features/src/template-resolver/handlers/send-test.write.ts +106 -112
- package/packages/bundled-features/src/template-resolver/handlers/set.write.ts +111 -104
- package/packages/bundled-features/src/template-resolver/handlers/shared.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/template-gates.ts +6 -6
- package/packages/bundled-features/src/template-resolver/handlers/template-write.ts +2 -2
- package/packages/bundled-features/src/template-resolver/handlers/toggle-status.write.ts +56 -28
- package/packages/bundled-features/src/template-resolver/handlers/upsert-tenant.write.ts +38 -29
- package/packages/bundled-features/src/template-resolver/handlers/usage.query.ts +8 -2
- package/packages/bundled-features/src/template-resolver/handlers/validate.query.ts +4 -2
- package/packages/bundled-features/src/template-resolver/i18n.ts +25 -0
- package/packages/bundled-features/src/template-resolver/index.ts +68 -60
- package/packages/bundled-features/src/template-resolver/layout-appearance.ts +1 -1
- package/packages/bundled-features/src/template-resolver/layout-regions.ts +1 -1
- package/packages/bundled-features/src/template-resolver/seeding.ts +16 -7
- package/packages/bundled-features/src/template-resolver/store-template-resource.ts +2 -2
- package/packages/bundled-features/src/template-resolver/table.ts +1 -1
- package/packages/bundled-features/src/template-resolver/template-bundle.ts +2 -2
- package/packages/bundled-features/src/template-resolver/template-delivery-policy.ts +82 -0
- package/packages/bundled-features/src/template-resolver/template-draft.ts +1 -1
- package/packages/bundled-features/src/template-resolver/template-edit-policy.ts +91 -0
- package/packages/bundled-features/src/template-resolver/template-meta.ts +2 -2
- package/packages/bundled-features/src/template-resolver/template-preview.ts +22 -12
- package/packages/bundled-features/src/template-resolver/template-usage.ts +1 -1
- package/packages/bundled-features/src/template-resolver/template-validation.ts +33 -12
- package/packages/bundled-features/src/template-resolver/testing.ts +2 -2
- package/packages/bundled-features/src/template-resolver/user-content-table.ts +1 -1
- package/packages/bundled-features/src/template-resolver/web/client-plugin.tsx +4 -5
- package/packages/bundled-features/src/template-resolver/{constants.ts → web/constants.ts} +10 -10
- package/packages/bundled-features/src/template-resolver/{document-blocks.ts → web/document-blocks.ts} +3 -2
- package/packages/bundled-features/src/template-resolver/web/document-editor-extensions.ts +31 -3
- package/packages/bundled-features/src/template-resolver/web/document-editor.tsx +0 -1
- package/packages/bundled-features/src/template-resolver/web/document-images.ts +28 -0
- package/packages/bundled-features/src/template-resolver/{document-schema.ts → web/document-schema.ts} +5 -1
- package/packages/bundled-features/src/template-resolver/{document-steps.ts → web/document-steps.ts} +0 -1
- package/packages/bundled-features/src/template-resolver/web/document-tiptap-editor.tsx +48 -11
- package/packages/bundled-features/src/template-resolver/web/document-toolbar-blocks.ts +4 -3
- package/packages/bundled-features/src/template-resolver/web/editor-handle.ts +1 -2
- package/packages/bundled-features/src/template-resolver/web/i18n.ts +8 -1
- package/packages/bundled-features/src/template-resolver/web/index.ts +13 -14
- package/packages/bundled-features/src/template-resolver/{mail-constants.ts → web/mail-constants.ts} +0 -1
- package/packages/bundled-features/src/template-resolver/{pdf-constants.ts → web/pdf-constants.ts} +0 -1
- package/packages/bundled-features/src/template-resolver/web/placeholder-line-editor-lazy.tsx +0 -1
- package/packages/bundled-features/src/template-resolver/web/placeholder-line-editor.tsx +5 -4
- package/packages/bundled-features/src/template-resolver/{placeholder-text.ts → web/placeholder-text.ts} +0 -1
- package/packages/bundled-features/src/template-resolver/{qualified-names.ts → web/qualified-names.ts} +2 -1
- package/packages/bundled-features/src/template-resolver/web/use-stable-by-key.ts +0 -1
- package/packages/bundled-features/src/tenant/handlers/add-member.write.ts +1 -1
- package/packages/bundled-features/src/tenant/index.ts +7 -7
- package/packages/bundled-features/src/tenant/invitation-table.ts +1 -1
- package/packages/bundled-features/src/tenant/invited-membership.ts +1 -1
- package/packages/bundled-features/src/tenant/last-tenant-admin.ts +1 -1
- package/packages/bundled-features/src/tenant/member-role-options.ts +1 -1
- package/packages/bundled-features/src/tenant/screens.ts +2 -2
- package/packages/bundled-features/src/tenant/web/client-plugin.tsx +1 -2
- package/packages/bundled-features/src/tenant/{constants.ts → web/constants.ts} +3 -6
- package/packages/bundled-features/src/tenant/web/index.ts +0 -1
- package/packages/bundled-features/src/tenant/web/member-roles-cell.tsx +0 -1
- package/packages/bundled-features/src/tenant/web/member-status-cell.tsx +0 -1
- package/packages/bundled-features/src/tenant-lifecycle/stages.ts +2 -2
- package/packages/bundled-features/src/tier-engine/entity.ts +1 -1
- package/packages/bundled-features/src/tier-engine/feature.ts +7 -7
- package/packages/bundled-features/src/tier-engine/handlers/set-tenant-tier.write.ts +1 -1
- package/packages/bundled-features/src/tier-engine/index.ts +8 -8
- package/packages/bundled-features/src/tier-engine/web/client-plugin.tsx +2 -3
- package/packages/bundled-features/src/tier-engine/{constants.ts → web/constants.ts} +2 -3
- package/packages/bundled-features/src/tier-engine/{i18n.ts → web/i18n.ts} +0 -1
- package/packages/bundled-features/src/tier-engine/web/index.ts +0 -1
- package/packages/bundled-features/src/user/handlers/create.write.ts +1 -1
- package/packages/bundled-features/src/user/handlers/update-roles.ts +1 -1
- package/packages/bundled-features/src/user/handlers/update.write.ts +1 -1
- package/packages/bundled-features/src/user/index.ts +1 -1
- package/packages/bundled-features/src/user/invited-global-roles.ts +1 -1
- package/packages/bundled-features/src/user/schema/user.ts +1 -1
- package/packages/bundled-features/src/user/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/user-data-rights/changes.json +14 -0
- package/packages/bundled-features/src/user-data-rights/env.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/feature.ts +9 -9
- package/packages/bundled-features/src/user-data-rights/index.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/lib/resolve-tenant-model.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/mail-notifications.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/web/client-plugin.tsx +2 -3
- package/packages/bundled-features/src/user-data-rights/web/confirm-deletion-screen.tsx +0 -1
- package/packages/bundled-features/src/user-data-rights/{constants.ts → web/constants.ts} +11 -12
- package/packages/bundled-features/src/user-data-rights/web/default-translations.ts +91 -0
- package/packages/bundled-features/src/user-data-rights/web/i18n.ts +41 -91
- package/packages/bundled-features/src/user-data-rights/web/index.ts +1 -2
- package/packages/bundled-features/src/user-data-rights/web/privacy-center-screen.tsx +1 -2
- package/packages/bundled-features/src/user-data-rights/web/public-deletion-gate.tsx +0 -1
- package/packages/bundled-features/src/user-data-rights/web/request-deletion-screen.tsx +0 -1
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/file-ref.userdata-hook.ts +10 -1
- package/packages/bundled-features/src/user-profile/feature.ts +2 -2
- package/packages/bundled-features/src/user-profile/handlers/change-email.write.ts +1 -1
- package/packages/bundled-features/src/user-profile/index.ts +3 -2
- package/packages/bundled-features/src/user-profile/web/client-plugin.ts +2 -3
- package/packages/bundled-features/src/user-profile/{constants.ts → web/constants.ts} +0 -1
- package/packages/bundled-features/src/user-profile/{i18n.ts → web/i18n.ts} +0 -1
- package/packages/bundled-features/src/user-profile/web/profile-screen.tsx +2 -3
- package/packages/bundled-features/src/waitlist/changes.json +6 -0
- package/packages/bundled-features/src/waitlist/entity.ts +1 -1
- package/packages/bundled-features/src/waitlist/feature.ts +5 -5
- package/packages/bundled-features/src/waitlist/handlers/export-purge.write.ts +3 -3
- package/packages/bundled-features/src/waitlist/handlers/invite.write.ts +5 -1
- package/packages/bundled-features/src/waitlist/handlers/reject.write.ts +1 -1
- package/packages/bundled-features/src/waitlist/handlers/submit.write.ts +3 -3
- package/packages/bundled-features/src/waitlist/import.ts +1 -1
- package/packages/bundled-features/src/waitlist/index.ts +11 -11
- package/packages/bundled-features/src/waitlist/legacy-migrate.ts +1 -1
- package/packages/bundled-features/src/waitlist/link-on-signup.ts +1 -1
- package/packages/bundled-features/src/waitlist/mail.ts +7 -6
- package/packages/bundled-features/src/waitlist/payloads.ts +1 -1
- package/packages/bundled-features/src/waitlist/screens.ts +1 -1
- package/packages/bundled-features/src/waitlist/{constants.ts → web/constants.ts} +0 -1
- package/samples/apps/styleguide/src/features/content/web.tsx +0 -1
- package/samples/apps/ui-walkthrough/src/app/client.tsx +2 -0
- package/samples/apps/ui-walkthrough/src/app/help-action.tsx +37 -0
- package/samples/apps/ui-walkthrough/src/app/seed-rental.ts +17 -1
- package/samples/apps/ui-walkthrough/src/app/seed-templates.ts +13 -0
- package/samples/apps/ui-walkthrough/src/app/server.ts +2 -1
- package/samples/apps/ui-walkthrough/src/app/shell.tsx +6 -0
- package/samples/apps/ui-walkthrough/src/app/template-seed-data.ts +20 -0
- package/samples/apps/ui-walkthrough/src/features/billing/feature.ts +35 -7
- package/samples/apps/ui-walkthrough/src/features/billing/i18n.ts +6 -0
- package/samples/apps/ui-walkthrough/src/features/rental/entities.ts +27 -0
- package/samples/apps/ui-walkthrough/src/features/rental/feature.ts +120 -2
- package/samples/apps/ui-walkthrough/src/features/rental/i18n.ts +94 -0
- package/samples/apps/ui-walkthrough/src/features/rental/invoice-receive.ts +19 -0
- package/samples/apps/ui-walkthrough/src/features/rental/lease-support.ts +32 -1
- package/samples/apps/ui-walkthrough/src/features/rental/qualified-names.ts +5 -0
- package/samples/apps/ui-walkthrough/src/features/rental/receipts-upload.ts +70 -0
- package/samples/apps/ui-walkthrough/src/features/rental/screens.ts +156 -0
- package/samples/apps/ui-walkthrough/src/features/subscription-plans/feature.ts +103 -0
- package/samples/apps/ui-walkthrough/src/features/subscription-plans/i18n.ts +36 -0
- package/samples/apps/ui-walkthrough/src/features/subscription-plans/index.ts +2 -0
- package/samples/apps/ui-walkthrough/src/features/subscription-plans/seed.ts +21 -0
- package/samples/apps/ui-walkthrough/src/features/tasks/i18n.ts +8 -0
- package/samples/apps/ui-walkthrough/src/run-config.ts +43 -3
- package/samples/apps/use-all-bundled/e2e-billing-gallery/server.ts +1 -1
- package/samples/apps/use-all-bundled/feature-manifest.json +5 -5
- package/samples/apps/use-all-bundled/scripts/check-coverage.ts +1 -1
- package/samples/apps/use-all-bundled/src/app/dev-app-options.ts +3 -1
- package/samples/recipes/compose-stacks/README.md +1 -2
- package/samples/recipes/delivery-notifications/README.md +1 -1
- package/samples/recipes/embedded/README.md +8 -0
- package/samples/recipes/embedded/src/feature.ts +8 -0
- package/samples/recipes/embedded/src/handlers/invoice-receive.write.ts +37 -0
- package/samples/recipes/embedded/src/screens/invoice-receive.screen.ts +56 -0
- package/samples/recipes/legal-pages/README.md +2 -2
- package/samples/recipes/legal-pages/src/feature.ts +1 -1
- package/samples/recipes/reference-data/src/feature.ts +3 -7
- package/packages/bundled-features/src/admin-shell/i18n.ts +0 -54
- package/packages/bundled-features/src/audit/i18n.ts +0 -25
- package/packages/bundled-features/src/auth-mfa/web/qrcode-browser.d.ts +0 -11
- package/packages/bundled-features/src/jobs/i18n.ts +0 -55
- package/packages/bundled-features/src/managed-pages/i18n.ts +0 -63
- package/packages/bundled-features/src/presets/dsgvo-self-service.ts +0 -35
- package/packages/bundled-features/src/user-data-rights/i18n.ts +0 -44
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @runtime client
|
|
2
1
|
// Default translation bundle for the tags UI. tagsClient() hangs it into the
|
|
3
2
|
// LocaleProvider as a fallback bundle — apps override individual keys via
|
|
4
3
|
// tagsClient({ translations }). Keys follow `tags.<area>.<slug>`.
|
|
@@ -25,7 +24,8 @@ export const defaultTranslations: TranslationsByLocale = {
|
|
|
25
24
|
"tags.manage.toggle": "Toggle label",
|
|
26
25
|
"tags.manage.usage": "{count}×",
|
|
27
26
|
"tags.manage.deleteConfirmTitle": "Delete label “{name}”?",
|
|
28
|
-
"tags.manage.deleteConfirmDesc": "Removes it from
|
|
27
|
+
"tags.manage.deleteConfirmDesc.one": "Removes it from 1 object. This can't be undone.",
|
|
28
|
+
"tags.manage.deleteConfirmDesc.other": "Removes it from {count} objects. This can't be undone.",
|
|
29
29
|
"tags.picker.title": "Tags",
|
|
30
30
|
"tags.picker.done": "Done",
|
|
31
31
|
"tags.filter.label": "Filter by tag",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
export { tagsClient } from "./client-plugin.tsx";
|
|
2
2
|
export {
|
|
3
3
|
TAGS_COLUMN_RENDERER_NAME,
|
|
4
4
|
TAGS_EDIT_SCREEN_ID,
|
|
@@ -7,8 +7,7 @@ export {
|
|
|
7
7
|
TAGS_SECTION_EXTENSION_NAME,
|
|
8
8
|
TagsHandlers,
|
|
9
9
|
TagsQueries,
|
|
10
|
-
} from "
|
|
11
|
-
export { tagsClient } from "./client-plugin.tsx";
|
|
10
|
+
} from "./constants.ts";
|
|
12
11
|
export { EntityTags } from "./entity-tags.tsx";
|
|
13
12
|
export { contrastText, TagChip } from "./tag-chip.tsx";
|
|
14
13
|
export { TagFilter } from "./tag-filter.tsx";
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @runtime client
|
|
2
1
|
// TagFilter — a drop-in tag filter for ANY entityList toolbar. Register it as
|
|
3
2
|
// the list's header slot (`screen.slots.header`); the renderer passes it the
|
|
4
3
|
// list's screenId, and picking tags resolves the matching row ids and narrows
|
|
@@ -20,7 +19,7 @@ import {
|
|
|
20
19
|
useTranslation,
|
|
21
20
|
} from "@cosmicdrift/kumiko-renderer";
|
|
22
21
|
import { type ReactNode, useState } from "react";
|
|
23
|
-
import { TagsQueries } from "
|
|
22
|
+
import { TagsQueries } from "./constants.ts";
|
|
24
23
|
import { TagChip } from "./tag-chip.tsx";
|
|
25
24
|
import { TagPicker } from "./tag-picker.tsx";
|
|
26
25
|
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @runtime client
|
|
2
1
|
// TagManager — the shared tag-catalog UI, GitLab-labels style. Built ONCE,
|
|
3
2
|
// mounted twice:
|
|
4
3
|
// - standalone: <TagManager /> → the Tags admin screen
|
|
@@ -16,8 +15,9 @@ import {
|
|
|
16
15
|
useQuery,
|
|
17
16
|
useTranslation,
|
|
18
17
|
} from "@cosmicdrift/kumiko-renderer";
|
|
18
|
+
import { pluralKey } from "@cosmicdrift/kumiko-renderer/headless";
|
|
19
19
|
import { type ReactNode, useState } from "react";
|
|
20
|
-
import { TagsHandlers, TagsQueries } from "
|
|
20
|
+
import { TagsHandlers, TagsQueries } from "./constants.ts";
|
|
21
21
|
import { TagChip } from "./tag-chip.tsx";
|
|
22
22
|
|
|
23
23
|
type TagRow = {
|
|
@@ -139,6 +139,7 @@ export function TagManager({
|
|
|
139
139
|
const usage = new Map<string, number>();
|
|
140
140
|
for (const a of assignments.data?.rows ?? []) usage.set(a.tagId, (usage.get(a.tagId) ?? 0) + 1);
|
|
141
141
|
|
|
142
|
+
const deletingUsage = usage.get(deleting?.id ?? "") ?? 0;
|
|
142
143
|
const selecting = selection !== undefined;
|
|
143
144
|
const allTags = catalog.data?.rows ?? [];
|
|
144
145
|
const tags = selecting
|
|
@@ -378,8 +379,8 @@ export function TagManager({
|
|
|
378
379
|
if (!open) setDeleting(null);
|
|
379
380
|
}}
|
|
380
381
|
title={t("tags.manage.deleteConfirmTitle", { name: deleting?.name ?? "" })}
|
|
381
|
-
description={t("tags.manage.deleteConfirmDesc", {
|
|
382
|
-
count:
|
|
382
|
+
description={t(pluralKey("tags.manage.deleteConfirmDesc", deletingUsage), {
|
|
383
|
+
count: deletingUsage,
|
|
383
384
|
})}
|
|
384
385
|
confirmLabel={t("tags.manage.delete")}
|
|
385
386
|
variant="danger"
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @runtime client
|
|
2
1
|
// TagSection — drop-in tag editor for ANY entity, GitLab-labels style. Shows the
|
|
3
2
|
// entity's tags as colored chips plus an "Edit tags" button that opens the
|
|
4
3
|
// shared TagPicker modal (pick + manage). Applying the picker diffs the
|
|
@@ -19,7 +18,7 @@ import {
|
|
|
19
18
|
useTranslation,
|
|
20
19
|
} from "@cosmicdrift/kumiko-renderer";
|
|
21
20
|
import { type ReactNode, useState } from "react";
|
|
22
|
-
import { TagsHandlers, TagsQueries } from "
|
|
21
|
+
import { TagsHandlers, TagsQueries } from "./constants.ts";
|
|
23
22
|
import { TagChip } from "./tag-chip.tsx";
|
|
24
23
|
import { TagPicker } from "./tag-picker.tsx";
|
|
25
24
|
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @runtime client
|
|
2
1
|
// TagsCell — a reusable columnRenderer that shows an entity's tags as colored
|
|
3
2
|
// chips inline in a list row. Drop it into ANY entityList by declaring a labeled
|
|
4
3
|
// virtual column (no host-schema change), after mounting tagsClient():
|
|
@@ -17,7 +16,7 @@
|
|
|
17
16
|
|
|
18
17
|
import { type ColumnRendererProps, useQuery } from "@cosmicdrift/kumiko-renderer";
|
|
19
18
|
import type { ReactNode } from "react";
|
|
20
|
-
import { TagsQueries } from "
|
|
19
|
+
import { TagsQueries } from "./constants.ts";
|
|
21
20
|
import { TagChip } from "./tag-chip.tsx";
|
|
22
21
|
|
|
23
22
|
type TagRow = { readonly id: string; readonly name: string; readonly color?: string | null };
|
|
@@ -4,12 +4,10 @@
|
|
|
4
4
|
|
|
5
5
|
import type { DbRunner, TenantDb } from "@cosmicdrift/kumiko-framework/db";
|
|
6
6
|
import { selectMany } from "@cosmicdrift/kumiko-framework/db";
|
|
7
|
-
import type { SessionUser, TenantId } from "@cosmicdrift/kumiko-framework/engine";
|
|
7
|
+
import type { Registry, SessionUser, TenantId } from "@cosmicdrift/kumiko-framework/engine";
|
|
8
8
|
import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
|
|
9
9
|
import type { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
10
10
|
import type { FileAttachmentRef } from "../renderer-foundation/index.ts";
|
|
11
|
-
import type { ContentFormat, TemplateKind } from "./constants.ts";
|
|
12
|
-
import { FALLBACK_LOCALE, SYSTEM_TENANT_ID } from "./constants.ts";
|
|
13
11
|
import {
|
|
14
12
|
fileAttachmentsOf,
|
|
15
13
|
imageLinksOf,
|
|
@@ -18,8 +16,16 @@ import {
|
|
|
18
16
|
type TemplatePdfAttachmentLink,
|
|
19
17
|
} from "./linked-resources.ts";
|
|
20
18
|
import { type TemplateResourceRow, templateResourcesTable } from "./table.ts";
|
|
21
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
deliveryPolicyOf,
|
|
21
|
+
isRowServed,
|
|
22
|
+
isServedByCollectionOnly,
|
|
23
|
+
type TemplateDeliveryPolicy,
|
|
24
|
+
} from "./template-delivery-policy.ts";
|
|
25
|
+
import { activeVersionOf, isSystemAdmin, servedVersionOf } from "./template-draft.ts";
|
|
22
26
|
import { parseTemplateMeta, type TemplateMeta } from "./template-meta.ts";
|
|
27
|
+
import type { ContentFormat, TemplateKind } from "./web/constants.ts";
|
|
28
|
+
import { FALLBACK_LOCALE, SYSTEM_TENANT_ID } from "./web/constants.ts";
|
|
23
29
|
|
|
24
30
|
// Public TemplateResource: what consumers see. Hides DB-internal columns
|
|
25
31
|
// (insertedById, internal id-type) but keeps the fields needed for rendering.
|
|
@@ -68,15 +74,11 @@ export type ResolveLayoutRequest = {
|
|
|
68
74
|
|
|
69
75
|
export type TemplateResolverApi = {
|
|
70
76
|
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
* `resolveTemplate` nutzen.
|
|
77
|
+
* Raw lookup by (tenantId, slug, kind, locale): no locale fallback, no override
|
|
78
|
+
* hierarchy. Render paths must use `resolveTemplate`. `scope: "system"` forces
|
|
79
|
+
* SYSTEM_TENANT_ID and ignores the passed tenantId.
|
|
75
80
|
*
|
|
76
|
-
*
|
|
77
|
-
* den übergebenen tenantId). Default = Lookup gegen den übergebenen
|
|
78
|
-
* tenantId direkt (Caller wählt entweder Tenant oder System per
|
|
79
|
-
* tenantId).
|
|
81
|
+
* Tenant rows of a template that is not tenantEditable are not returned.
|
|
80
82
|
*/
|
|
81
83
|
readonly findExact: (args: {
|
|
82
84
|
readonly tenantId: TenantId;
|
|
@@ -87,18 +89,10 @@ export type TemplateResolverApi = {
|
|
|
87
89
|
}) => Promise<TemplateResource | null>;
|
|
88
90
|
|
|
89
91
|
/**
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
* 4. system + FALLBACK_LOCALE
|
|
95
|
-
* Resource-Substitution wird hier NICHT ausgeführt — das macht der
|
|
96
|
-
* Caller (renderer-foundation-Plugin) je nach kind-passendem Modus
|
|
97
|
-
* (inline-base64 vs. signed-url). API liefert TemplateResource pur.
|
|
98
|
-
*
|
|
99
|
-
* **Caller-Invariante:** `tenantId` MUSS vom Server kommen (typisch
|
|
100
|
-
* `ctx.user.tenantId`). Niemals direkt aus User-Input — sonst kann
|
|
101
|
-
* User cross-tenant Templates abfragen (Tenant-Isolation gebrochen).
|
|
92
|
+
* Four-step fallback: tenant+locale, system+locale, tenant+FALLBACK_LOCALE,
|
|
93
|
+
* system+FALLBACK_LOCALE (see template-resolver.md).
|
|
94
|
+
* Tenant rows count only for templates unlocked for tenants (tenantEditable,
|
|
95
|
+
* or a collection with access); locked overrides are skipped but stay stored.
|
|
102
96
|
*/
|
|
103
97
|
readonly resolveTemplate: (args: ResolveRequest) => Promise<TemplateResource>;
|
|
104
98
|
|
|
@@ -114,12 +108,18 @@ export type TemplateResolverApi = {
|
|
|
114
108
|
readonly resolveLayout: (args: ResolveLayoutRequest) => Promise<TemplateResource>;
|
|
115
109
|
};
|
|
116
110
|
|
|
117
|
-
export function createTemplateResolverApi(
|
|
111
|
+
export function createTemplateResolverApi(
|
|
112
|
+
db: DbRunner | TenantDb,
|
|
113
|
+
registry: Registry,
|
|
114
|
+
): TemplateResolverApi {
|
|
115
|
+
const deliveryPolicy = deliveryPolicyOf(registry);
|
|
116
|
+
// A collection entry must not shadow a system template of the same slug that the app did not unlock.
|
|
117
|
+
const isServed = (row: TemplateResourceRow) => isRowDelivered(db, deliveryPolicy, row);
|
|
118
118
|
return {
|
|
119
119
|
findExact: async ({ tenantId, slug, kind, locale, scope }) => {
|
|
120
120
|
const effectiveTenantId = scope === "system" ? SYSTEM_TENANT_ID : tenantId;
|
|
121
121
|
const row = await fetchTemplate(db, effectiveTenantId, slug, kind, locale);
|
|
122
|
-
return row ? toPublic(row) : null;
|
|
122
|
+
return row && (await isServed(row)) ? toPublic(row) : null;
|
|
123
123
|
},
|
|
124
124
|
|
|
125
125
|
resolveTemplate: async ({ tenantId, slug, kind, locale }) => {
|
|
@@ -135,14 +135,16 @@ export function createTemplateResolverApi(db: DbRunner | TenantDb): TemplateReso
|
|
|
135
135
|
: []),
|
|
136
136
|
];
|
|
137
137
|
for (const c of candidates) {
|
|
138
|
+
if (!isRowServed(deliveryPolicy, { tenantId: c.tid, kind, slug })) continue;
|
|
138
139
|
const row = await fetchTemplate(db, c.tid, slug, kind, c.loc);
|
|
139
|
-
if (row && row.status === "active") return toPublic(row);
|
|
140
|
+
if (row && row.status === "active" && (await isServed(row))) return toPublic(row);
|
|
140
141
|
}
|
|
141
142
|
throw new TemplateNotFoundError({ slug, kind, locale });
|
|
142
143
|
},
|
|
143
144
|
|
|
144
145
|
resolveLayout: async ({ tenantId, slug, kind, locale }) => {
|
|
145
146
|
for (const tid of [tenantId, SYSTEM_TENANT_ID]) {
|
|
147
|
+
if (!isRowServed(deliveryPolicy, { tenantId: tid, kind, slug })) continue;
|
|
146
148
|
const rows = await selectMany<TemplateResourceRow>(db, templateResourcesTable, {
|
|
147
149
|
tenantId: tid,
|
|
148
150
|
slug,
|
|
@@ -156,6 +158,51 @@ export function createTemplateResolverApi(db: DbRunner | TenantDb): TemplateReso
|
|
|
156
158
|
};
|
|
157
159
|
}
|
|
158
160
|
|
|
161
|
+
// The one delivery rule for a stored row: unlocked, and a collection entry never shadows a system
|
|
162
|
+
// template of the same slug that the app did not unlock.
|
|
163
|
+
export async function isRowDelivered(
|
|
164
|
+
db: DbRunner | TenantDb,
|
|
165
|
+
policy: TemplateDeliveryPolicy,
|
|
166
|
+
row: TemplateResourceRow,
|
|
167
|
+
): Promise<boolean> {
|
|
168
|
+
if (!isRowServed(policy, row)) return false;
|
|
169
|
+
if (row.tenantId === SYSTEM_TENANT_ID || !isServedByCollectionOnly(policy, row)) return true;
|
|
170
|
+
return !(await systemTemplateExists(db, row.kind, row.slug));
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export async function isRowDeliveredTo(
|
|
174
|
+
db: DbRunner | TenantDb,
|
|
175
|
+
policy: TemplateDeliveryPolicy,
|
|
176
|
+
user: { readonly roles: readonly string[] },
|
|
177
|
+
row: TemplateResourceRow,
|
|
178
|
+
): Promise<boolean> {
|
|
179
|
+
return isSystemAdmin(user) || (await isRowDelivered(db, policy, row));
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export async function filterDeliveredTo(
|
|
183
|
+
db: DbRunner | TenantDb,
|
|
184
|
+
policy: TemplateDeliveryPolicy,
|
|
185
|
+
user: { readonly roles: readonly string[] },
|
|
186
|
+
rows: readonly TemplateResourceRow[],
|
|
187
|
+
): Promise<TemplateResourceRow[]> {
|
|
188
|
+
const flags = await Promise.all(rows.map((row) => isRowDeliveredTo(db, policy, user, row)));
|
|
189
|
+
return rows.filter((_, index) => flags[index]);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export async function systemTemplateExists(
|
|
193
|
+
db: DbRunner | TenantDb,
|
|
194
|
+
kind: string,
|
|
195
|
+
slug: string,
|
|
196
|
+
): Promise<boolean> {
|
|
197
|
+
const rows = await selectMany(
|
|
198
|
+
db,
|
|
199
|
+
templateResourcesTable,
|
|
200
|
+
{ tenantId: SYSTEM_TENANT_ID, slug, kind },
|
|
201
|
+
{ limit: 1 },
|
|
202
|
+
);
|
|
203
|
+
return rows.length > 0;
|
|
204
|
+
}
|
|
205
|
+
|
|
159
206
|
function pickActiveLayoutRow(
|
|
160
207
|
rows: readonly TemplateResourceRow[],
|
|
161
208
|
locale: string,
|
|
@@ -268,7 +315,7 @@ export function requireTemplateResolver(
|
|
|
268
315
|
throw new InternalError({
|
|
269
316
|
message:
|
|
270
317
|
`[${callerName}] ctx.templateResolver missing — App-Bootstrap muss ` +
|
|
271
|
-
`extraContext: { templateResolver: createTemplateResolverApi(db) } setzen ` +
|
|
318
|
+
`extraContext: { templateResolver: createTemplateResolverApi(db, registry) } setzen ` +
|
|
272
319
|
`(siehe template-resolver/README.md).`,
|
|
273
320
|
});
|
|
274
321
|
}
|
|
@@ -1,4 +1,67 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.379.0",
|
|
4
|
+
"type": "improvement",
|
|
5
|
+
"title": "Titles for the template-resolver write handlers",
|
|
6
|
+
"detail": "Every agent-callable template-resolver write handler now has a title in de, en, es, fr and it, so the AI assistant names actions such as \"Edit template draft\" instead of \"template-resolver:write:patch-draft\". The handlers of mounted content collections (`<id>-set`) stay untitled because their names depend on the app. The empty-field hint of the placeholder line editor now ends in an ellipsis inside the field instead of running past it."
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"version": "0.379.0",
|
|
10
|
+
"type": "breaking",
|
|
11
|
+
"title": "Overrides of locked templates are no longer served",
|
|
12
|
+
"detail": "A tenant override of a mail, PDF or layout template is delivered (mail send, PDF render, linked PDFs, layouts, previews, export bundles, document blocks, overview, text blocks) only while the template is listed in tenantEditable. A locked override stays stored and has no effect; listing the template makes it effective again, nothing is deleted. A SystemAdmin sees locked overrides in the overview (`lockedOverride`, `lockedOverrideI18nKey`) and can reset or archive them with the existing handlers; the template-resolver queries do not show them to a TenantAdmin; the audit log keeps the history. Tenant rows of a collection mounted with `access` are served, except for a slug that has a system template outside tenantEditable: that system template wins, and the collection `-set` handler refuses such a slug for a non-SystemAdmin. createTemplateResolverApi(db) became createTemplateResolverApi(db, registry) because the delivery policy is read from the mounted feature; without the mounted feature no tenant override is served.",
|
|
13
|
+
"migration": "Overrides of templates that are not tenantEditable are no longer served; enable the template via tenantEditable to keep using them. Pass the registry as second argument to createTemplateResolverApi (ctx.registry in handlers, stack.registry in tests). Tenant rows without a system counterpart (for example text blocks seeded directly into a tenant) are hidden as well unless listed in tenantEditable."
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"version": "0.379.0",
|
|
17
|
+
"type": "improvement",
|
|
18
|
+
"title": "Overview label for locked template overrides",
|
|
19
|
+
"detail": "Adds templateResolver.overview.lockedOverride."
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"version": "0.379.0",
|
|
23
|
+
"type": "improvement",
|
|
24
|
+
"title": "Mail rendering follows the template delivery policy",
|
|
25
|
+
"detail": "Resolves templates through createTemplateResolverApi(db, registry); overrides of locked templates fall back to the system version."
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"version": "0.379.0",
|
|
29
|
+
"type": "improvement",
|
|
30
|
+
"title": "PDF rendering follows the template delivery policy",
|
|
31
|
+
"detail": "Resolves templates through createTemplateResolverApi(db, registry); overrides of locked templates fall back to the system version."
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"version": "0.379.0",
|
|
35
|
+
"type": "improvement",
|
|
36
|
+
"title": "Samples follow the createTemplateResolverApi(db, registry) signature",
|
|
37
|
+
"detail": "Recipes and sample apps build the template resolver API with the registry as second argument."
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"version": "0.379.0",
|
|
41
|
+
"type": "improvement",
|
|
42
|
+
"title": "seedSystemTemplate accepts titleI18nKey",
|
|
43
|
+
"detail": "A seeded template can store an i18n key as its title (titleI18nKey, exclusive with title). The overview returns the key; the document-designer overview, mail editor and PDF link modal translate it and fall back to the raw text. Templates without a key behave as before; no migration."
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"version": "0.378.0",
|
|
47
|
+
"type": "improvement",
|
|
48
|
+
"title": "Document PDFs embed the images of a record",
|
|
49
|
+
"detail": "A template variable of type images (templateVariable.images()) holds FileRef ids of the record. The new Images block (div[data-images], PDF templates only, rejected for mail kinds) renders them as data-URI images in the real PDF render. Only files of the rendering tenant are read, only png, jpeg, gif and webp, at most 24 images and 20 MB per document; missing, foreign, oversized or non-image ids are dropped silently. Previews and draft PDFs never read files and show one placeholder box per block. An images variable never renders as inline text. i18n keys template-resolver.documentEditor.images, template-resolver.documentEditor.imagesVariable and templateResolver.errors.document.imagesBlockPdfOnly ship in de, es, fr and it.",
|
|
50
|
+
"migration": "Declare a template variable with type `images`, place the Images block, and pass FileRef ids of the record in `variables`. Images resolve only in the real PDF render, previews show placeholders. The ids must come from the record on the server, never from client input: a resolved id is read for the whole tenant without an entity access check."
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"version": "0.378.0",
|
|
54
|
+
"type": "breaking",
|
|
55
|
+
"title": "Template editing is SystemAdmin-only unless the app unlocks it",
|
|
56
|
+
"detail": "Every tenant write handler, the overview and resource upload accept SystemAdmin only, plus the roles of the tenantEditable entries. A write on a template that is not unlocked fails with templateNotTenantEditable. The test send follows the same rule. For a non-SystemAdmin an unknown template id answers 403 like a locked one, so the response does not reveal whether it exists. Collections without an access rule default to SystemAdmin.",
|
|
57
|
+
"migration": "Where TenantAdmins must keep editing a template, pass tenantEditable to createTemplateResolverFeature, for example tenantEditable: [{ kind: \"mail\", slug: \"billing:notify:invoice-issued\", access: { roles: [\"TenantAdmin\"] } }]. Give template collections an explicit access rule if tenants should manage them."
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"version": "0.378.0",
|
|
61
|
+
"type": "improvement",
|
|
62
|
+
"title": "send-test-status query for the template test mail",
|
|
63
|
+
"detail": "template-resolver:query:send-test-status answers whether a test mail can be sent (canSend) and, if not, why (no_channel or no_address), so clients can disable the action instead of failing on send."
|
|
64
|
+
},
|
|
2
65
|
{
|
|
3
66
|
"version": "0.377.0",
|
|
4
67
|
"type": "improvement",
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
isDocumentPlaceholderHref,
|
|
12
12
|
isDocumentReferenceName,
|
|
13
13
|
isDocumentResourceKey,
|
|
14
|
-
} from "./document-schema.ts";
|
|
14
|
+
} from "./web/document-schema.ts";
|
|
15
15
|
|
|
16
16
|
// Private-use characters mark where a Handlebars expression goes. Author text
|
|
17
17
|
// is scrubbed of them first and every `{`/`}` is entity-encoded before the
|
|
@@ -78,10 +78,15 @@ function valueExpression(
|
|
|
78
78
|
return `{{${path}}}`;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
// Never interpolated as text: its value is a list of file ids.
|
|
82
|
+
function isImagesVariable(def: TemplateVariableDef | undefined): boolean {
|
|
83
|
+
return def?.type === "images";
|
|
84
|
+
}
|
|
85
|
+
|
|
81
86
|
function rewriteVariable(element: ScanElement, state: CompileState): void {
|
|
82
87
|
const name = element.getAttribute("data-variable") ?? "";
|
|
83
88
|
const replacement = element.ownerDocument.createTextNode(
|
|
84
|
-
isDocumentReferenceName(name)
|
|
89
|
+
isDocumentReferenceName(name) && !isImagesVariable(pathAndDef(name, element, state)[1])
|
|
85
90
|
? marker(
|
|
86
91
|
state,
|
|
87
92
|
valueExpression(
|
|
@@ -131,6 +136,8 @@ function wrapVariableOnlyBlock(block: ScanElement, state: CompileState): void {
|
|
|
131
136
|
// skip: a line with static content or several placeholders stays as it is
|
|
132
137
|
if (name === null) return;
|
|
133
138
|
const [path, def] = pathAndDef(name, block, state);
|
|
139
|
+
// skip: images blocks are rewritten by rewriteImagesBlock
|
|
140
|
+
if (isImagesVariable(def)) return;
|
|
134
141
|
const host =
|
|
135
142
|
def?.type === "richText" && block.tagName === "P" ? richTextBlockHost(block, state) : block;
|
|
136
143
|
const document = host.ownerDocument;
|
|
@@ -158,8 +165,8 @@ function rewriteLink(element: ScanElement, state: CompileState): void {
|
|
|
158
165
|
if (isDocumentPlaceholderHref(href)) {
|
|
159
166
|
const name = href.slice(2, -2);
|
|
160
167
|
if (isDocumentReferenceName(name)) {
|
|
161
|
-
const [path] = pathAndDef(name, element, state);
|
|
162
|
-
element.setAttribute("href", marker(state, `{{link ${path}}}`));
|
|
168
|
+
const [path, def] = pathAndDef(name, element, state);
|
|
169
|
+
element.setAttribute("href", isImagesVariable(def) ? "#" : marker(state, `{{link ${path}}}`));
|
|
163
170
|
} else {
|
|
164
171
|
element.setAttribute("href", "#");
|
|
165
172
|
}
|
|
@@ -225,8 +232,14 @@ export type CompileDocumentBodyOptions = {
|
|
|
225
232
|
readonly headingAsInlineStyle?: boolean;
|
|
226
233
|
// Bar color of reached stages in a steps block; ignored unless it is a #rrggbb hex.
|
|
227
234
|
readonly stepsColor?: string;
|
|
235
|
+
// Data URIs of the record's images for the images block bound to `variable`.
|
|
236
|
+
readonly recordImagesSrc?: (variable: string) => readonly string[];
|
|
237
|
+
// Previews and drafts never read the record's files; each images block shows one neutral box.
|
|
238
|
+
readonly recordImagesPlaceholder?: boolean;
|
|
228
239
|
};
|
|
229
240
|
|
|
241
|
+
const IMAGES_PLACEHOLDER_STYLE = "height:96px;margin:8px 0;border-radius:4px;background:#e5e7eb";
|
|
242
|
+
|
|
230
243
|
const MAIL_BUTTON_STYLE =
|
|
231
244
|
"display:inline-block;padding:10px 20px;border-radius:6px;background-color:#1f5468;color:#ffffff;font-weight:600;text-decoration:none";
|
|
232
245
|
|
|
@@ -258,6 +271,48 @@ export function collectDocumentResourceKeys(html: string): readonly string[] {
|
|
|
258
271
|
});
|
|
259
272
|
}
|
|
260
273
|
|
|
274
|
+
// Unique valid names of the images blocks in document order.
|
|
275
|
+
export function collectDocumentImageVariables(html: string): readonly string[] {
|
|
276
|
+
return withParsedDocument(html, (root) => {
|
|
277
|
+
const names = new Set<string>();
|
|
278
|
+
for (const element of Array.from(root.querySelectorAll("div[data-images]"))) {
|
|
279
|
+
const name = element.getAttribute("data-images") ?? "";
|
|
280
|
+
if (isDocumentReferenceName(name)) names.add(name);
|
|
281
|
+
}
|
|
282
|
+
return [...names];
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
function rewriteImagesBlock(
|
|
287
|
+
element: ScanElement,
|
|
288
|
+
state: CompileState,
|
|
289
|
+
options: CompileDocumentBodyOptions,
|
|
290
|
+
): void {
|
|
291
|
+
const name = element.getAttribute("data-images") ?? "";
|
|
292
|
+
const declared =
|
|
293
|
+
isDocumentReferenceName(name) && isImagesVariable(ownVariable(state.variables, name));
|
|
294
|
+
if (!declared) {
|
|
295
|
+
element.remove();
|
|
296
|
+
// skip: an images block bound to anything but a declared images variable renders nothing
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
const document = element.ownerDocument;
|
|
300
|
+
element.removeAttribute("data-images");
|
|
301
|
+
if (options.recordImagesPlaceholder === true) {
|
|
302
|
+
element.setAttribute("class", "kumiko-doc-image-placeholder");
|
|
303
|
+
element.setAttribute("style", IMAGES_PLACEHOLDER_STYLE);
|
|
304
|
+
// skip: preview and drafts never resolve record images
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
element.setAttribute("class", "kumiko-doc-images");
|
|
308
|
+
for (const src of options.recordImagesSrc?.(name) ?? []) {
|
|
309
|
+
const image = document.createElement("img");
|
|
310
|
+
image.setAttribute("src", src);
|
|
311
|
+
image.setAttribute("alt", "");
|
|
312
|
+
element.append(image);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
261
316
|
export function toResourceDataUri(contentType: string, bytes: Uint8Array): string {
|
|
262
317
|
if (!isResourceImageContentType(contentType)) {
|
|
263
318
|
throw new Error(`resource content type "${contentType}" cannot be embedded as an image`);
|
|
@@ -374,6 +429,9 @@ export function compileDocumentBodyToHandlebars(
|
|
|
374
429
|
color: options.stepsColor,
|
|
375
430
|
});
|
|
376
431
|
}
|
|
432
|
+
for (const element of Array.from(root.querySelectorAll("div[data-images]"))) {
|
|
433
|
+
rewriteImagesBlock(element, state, options);
|
|
434
|
+
}
|
|
377
435
|
for (const block of Array.from(root.querySelectorAll(`[${DOCUMENT_CONDITION_ATTRIBUTE}]`))) {
|
|
378
436
|
rewriteConditionalBlock(block, state);
|
|
379
437
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Element as ScanElement } from "happy-dom";
|
|
2
|
-
import { isDocumentReferenceName } from "./document-schema.ts";
|
|
3
|
-
import { readDocumentSteps } from "./document-steps.ts";
|
|
4
2
|
import { isHexColor } from "./layout-appearance.ts";
|
|
3
|
+
import { isDocumentReferenceName } from "./web/document-schema.ts";
|
|
4
|
+
import { readDocumentSteps } from "./web/document-steps.ts";
|
|
5
5
|
|
|
6
6
|
export const DEFAULT_STEPS_COLOR = "#1f5468";
|
|
7
7
|
const TODO_BAR_COLOR = "#ECEDEA";
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import type { FieldIssue } from "@cosmicdrift/kumiko-framework/errors";
|
|
2
2
|
import { getSchema, type JSONContent } from "@tiptap/core";
|
|
3
3
|
import * as z from "zod";
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
4
|
+
import { toVariableDef } from "./template-validation.ts";
|
|
5
|
+
import type { DocumentHtmlKind } from "./web/constants.ts";
|
|
6
|
+
import { documentBlocksForKind } from "./web/document-blocks.ts";
|
|
6
7
|
import {
|
|
7
8
|
DOCUMENT_TEXT_ALIGNMENTS,
|
|
8
9
|
documentExtensions,
|
|
9
10
|
isDocumentPlaceholderHref,
|
|
10
11
|
isDocumentReferenceName,
|
|
11
12
|
isDocumentResourceKey,
|
|
12
|
-
} from "./document-schema.ts";
|
|
13
|
-
import { contentToLine, lineToContent, singleLine } from "./placeholder-text.ts";
|
|
14
|
-
import { toVariableDef } from "./template-validation.ts";
|
|
13
|
+
} from "./web/document-schema.ts";
|
|
14
|
+
import { contentToLine, lineToContent, singleLine } from "./web/placeholder-text.ts";
|
|
15
15
|
|
|
16
16
|
export const MAX_DOCUMENT_OPS = 50;
|
|
17
17
|
|
|
@@ -5,8 +5,8 @@ import { isOneOf } from "@cosmicdrift/kumiko-types/type-guards";
|
|
|
5
5
|
import type { JSONContent } from "@tiptap/core";
|
|
6
6
|
import { generateHTML, generateJSON } from "@tiptap/html/server";
|
|
7
7
|
import { type Element as ScanElement, Window } from "happy-dom";
|
|
8
|
-
import type { ContentFormat } from "./constants.ts";
|
|
9
|
-
import { DOCUMENT_HTML_KINDS } from "./constants.ts";
|
|
8
|
+
import type { ContentFormat } from "./web/constants.ts";
|
|
9
|
+
import { DOCUMENT_HTML_KINDS } from "./web/constants.ts";
|
|
10
10
|
import {
|
|
11
11
|
DOCUMENT_CONDITION_ATTRIBUTE,
|
|
12
12
|
documentExtensions,
|
|
@@ -14,8 +14,8 @@ import {
|
|
|
14
14
|
isDocumentPlaceholderHref,
|
|
15
15
|
isDocumentReferenceName,
|
|
16
16
|
isDocumentResourceKey,
|
|
17
|
-
} from "./document-schema.ts";
|
|
18
|
-
import { isDocumentStepKey } from "./document-steps.ts";
|
|
17
|
+
} from "./web/document-schema.ts";
|
|
18
|
+
import { isDocumentStepKey } from "./web/document-steps.ts";
|
|
19
19
|
|
|
20
20
|
export type DocumentViolationCode =
|
|
21
21
|
| "script_element"
|
|
@@ -26,6 +26,7 @@ export type DocumentViolationCode =
|
|
|
26
26
|
| "invalid_reference_name"
|
|
27
27
|
| "embedded_content"
|
|
28
28
|
| "unsafe_attribute_value"
|
|
29
|
+
| "images_block_pdf_only"
|
|
29
30
|
| "button_href_not_placeholder"
|
|
30
31
|
| "document_requires_html_format"
|
|
31
32
|
| "layout_requires_mjml_format"
|
|
@@ -143,6 +144,7 @@ const REFERENCE_ATTRIBUTES: ReadonlyArray<readonly [string, (value: string) => b
|
|
|
143
144
|
[DOCUMENT_CONDITION_ATTRIBUTE, isDocumentReferenceName],
|
|
144
145
|
["data-resource", isDocumentResourceKey],
|
|
145
146
|
["data-steps", isDocumentReferenceName],
|
|
147
|
+
["data-images", isDocumentReferenceName],
|
|
146
148
|
["data-step", isDocumentStepKey],
|
|
147
149
|
];
|
|
148
150
|
|
|
@@ -313,6 +315,36 @@ function requiredFormatViolation(
|
|
|
313
315
|
return null;
|
|
314
316
|
}
|
|
315
317
|
|
|
318
|
+
const IMAGES_BLOCK_KIND = "document-pdf";
|
|
319
|
+
|
|
320
|
+
// The node is part of the shared document model, so a mail body would keep it after the
|
|
321
|
+
// rebuild; only a PDF resolves the record's images.
|
|
322
|
+
function imagesBlockViolation(input: {
|
|
323
|
+
readonly kind: string;
|
|
324
|
+
readonly contentFormat: ContentFormat;
|
|
325
|
+
readonly content: string | null;
|
|
326
|
+
}): DocumentViolation | null {
|
|
327
|
+
if (
|
|
328
|
+
input.kind === IMAGES_BLOCK_KIND ||
|
|
329
|
+
!isSanitizedHtmlKind(input.kind) ||
|
|
330
|
+
input.contentFormat !== "html" ||
|
|
331
|
+
input.content === null
|
|
332
|
+
) {
|
|
333
|
+
return null;
|
|
334
|
+
}
|
|
335
|
+
const hasImagesBlock = withParsedDocument(
|
|
336
|
+
input.content,
|
|
337
|
+
(body) => body.querySelector("div[data-images]") !== null,
|
|
338
|
+
);
|
|
339
|
+
return hasImagesBlock
|
|
340
|
+
? violation(
|
|
341
|
+
"images_block_pdf_only",
|
|
342
|
+
input.kind,
|
|
343
|
+
`Record images blocks are only allowed in templates of kind ${IMAGES_BLOCK_KIND}`,
|
|
344
|
+
)
|
|
345
|
+
: null;
|
|
346
|
+
}
|
|
347
|
+
|
|
316
348
|
export function sanitizeTemplateBody(input: {
|
|
317
349
|
readonly kind: string;
|
|
318
350
|
readonly contentFormat: ContentFormat;
|
|
@@ -320,6 +352,8 @@ export function sanitizeTemplateBody(input: {
|
|
|
320
352
|
}): SanitizeBodyResult {
|
|
321
353
|
const formatViolation = requiredFormatViolation(input.kind, input.contentFormat);
|
|
322
354
|
if (formatViolation !== null) return { ok: false, violations: [formatViolation] };
|
|
355
|
+
const imagesViolation = imagesBlockViolation(input);
|
|
356
|
+
if (imagesViolation !== null) return { ok: false, violations: [imagesViolation] };
|
|
323
357
|
if (
|
|
324
358
|
!isSanitizedHtmlKind(input.kind) ||
|
|
325
359
|
input.contentFormat !== "html" ||
|
|
@@ -340,6 +374,7 @@ const VIOLATION_I18N_KEYS: Readonly<Record<DocumentViolationCode, string>> = {
|
|
|
340
374
|
invalid_reference_name: "templateResolver.errors.document.invalidReferenceName",
|
|
341
375
|
embedded_content: "templateResolver.errors.document.embeddedContent",
|
|
342
376
|
unsafe_attribute_value: "templateResolver.errors.document.unsafeAttributeValue",
|
|
377
|
+
images_block_pdf_only: "templateResolver.errors.document.imagesBlockPdfOnly",
|
|
343
378
|
button_href_not_placeholder: "templateResolver.errors.document.buttonHrefNotPlaceholder",
|
|
344
379
|
document_requires_html_format: "templateResolver.errors.document.documentRequiresHtmlFormat",
|
|
345
380
|
layout_requires_mjml_format: "templateResolver.errors.document.layoutRequiresMjmlFormat",
|