simple-module-pagebuilder 0.0.7__tar.gz → 0.0.9__tar.gz

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.
Files changed (345) hide show
  1. simple_module_pagebuilder-0.0.7/README.md → simple_module_pagebuilder-0.0.9/PKG-INFO +82 -0
  2. simple_module_pagebuilder-0.0.7/PKG-INFO → simple_module_pagebuilder-0.0.9/README.md +58 -23
  3. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/package.json +2 -2
  4. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/boot.py +20 -2
  5. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/ConfirmDialog.tsx +14 -6
  6. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/DiffSummary.tsx +15 -6
  7. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/NewPageDialog.tsx +22 -23
  8. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/NoteDialog.tsx +12 -5
  9. simple_module_pagebuilder-0.0.9/pagebuilder/components/PageBoard.tsx +162 -0
  10. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/PageBoardCard.tsx +31 -22
  11. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/PageListFilters.tsx +12 -8
  12. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/PageListRow.tsx +12 -11
  13. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/ScheduledBadge.tsx +6 -1
  14. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/StatusBadge.tsx +6 -4
  15. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/TranslatePageDialog.tsx +22 -17
  16. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/blocks/Button.tsx +20 -20
  17. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/blocks/Columns.tsx +5 -4
  18. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/blocks/Heading.tsx +14 -14
  19. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/blocks/Image.test.tsx +10 -1
  20. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/blocks/Image.tsx +19 -14
  21. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/blocks/MediaPicker.tsx +16 -12
  22. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/blocks/Spacer.tsx +7 -6
  23. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/blocks/Text.tsx +12 -12
  24. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/editor/BlockOutline.tsx +5 -3
  25. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/editor/NarrowCanvas.tsx +14 -7
  26. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/editor/PageActions.tsx +12 -12
  27. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/editor/PageEditorToolbar.tsx +25 -23
  28. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/editor/PageInspectorDrawer.tsx +18 -2
  29. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/editor/PageSettingsPanel.tsx +19 -15
  30. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/editor/RevisionHistoryPanel.tsx +33 -14
  31. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/editor/SchedulePanel.tsx +9 -7
  32. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/editor/SeoPreview.tsx +8 -7
  33. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/editor/SeoSettingsPanel.tsx +24 -18
  34. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/editor/TranslationsPanel.tsx +24 -12
  35. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/layoutPuckConfig.tsx +10 -2
  36. simple_module_pagebuilder-0.0.9/pagebuilder/components/localizeConfig.test.ts +94 -0
  37. simple_module_pagebuilder-0.0.9/pagebuilder/components/localizeConfig.ts +113 -0
  38. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/media/MediaFilters.tsx +12 -7
  39. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/media/MediaFolderSidebar.tsx +11 -6
  40. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/media/MediaGrid.tsx +12 -8
  41. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/media/MediaHeader.tsx +5 -2
  42. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/media/MediaUploadQueue.tsx +11 -5
  43. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/media/MediaUsageList.tsx +13 -5
  44. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/puckConfig.test.tsx +23 -0
  45. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/puckConfig.tsx +7 -5
  46. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/snapshots/ImportPlanSummary.tsx +21 -13
  47. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/snapshots/SnapshotList.tsx +14 -15
  48. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/snapshots/UploadBundleDialog.tsx +10 -10
  49. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/snapshots/planSummary.ts +45 -20
  50. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgetCatalog.ts +13 -5
  51. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/accordion-widget.tsx +8 -5
  52. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/alert-widget.tsx +9 -8
  53. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/app-store-badges-widget.tsx +29 -14
  54. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/article-cards-widget.tsx +20 -16
  55. simple_module_pagebuilder-0.0.9/pagebuilder/components/widgets/call-to-action-widget.tsx +86 -0
  56. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/carousel-widget.tsx +12 -7
  57. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/centered-hero-widget.tsx +11 -7
  58. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/colored-action-list-widget.tsx +11 -10
  59. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/column-widget.tsx +14 -13
  60. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/contact-cards-widget.tsx +16 -12
  61. simple_module_pagebuilder-0.0.9/pagebuilder/components/widgets/contact-form-widget.tsx +75 -0
  62. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/container-widget.tsx +20 -19
  63. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/definition-list-widget.tsx +31 -12
  64. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/divider-widget.tsx +16 -11
  65. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/eyebrow-section-widget.tsx +5 -4
  66. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/faq-widget.tsx +15 -15
  67. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/feature-card-widget.tsx +9 -8
  68. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/feature-cards-render.tsx +7 -3
  69. simple_module_pagebuilder-0.0.9/pagebuilder/components/widgets/feature-cards-widget.tsx +139 -0
  70. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/feature-grid-widget.tsx +18 -11
  71. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/feature-showcase-widget.tsx +16 -12
  72. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/gallery-widget.tsx +16 -15
  73. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/grid-widget.tsx +12 -11
  74. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/hero-widget.tsx +28 -28
  75. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/html-widget.tsx +6 -5
  76. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/iframe-widget.tsx +8 -7
  77. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/leaderboard-widget.tsx +22 -15
  78. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/list-widget.tsx +6 -5
  79. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/logo-cloud-widget.tsx +12 -11
  80. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/markdown-widget.tsx +9 -8
  81. simple_module_pagebuilder-0.0.9/pagebuilder/components/widgets/media-object-widget.tsx +180 -0
  82. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/newsletter-widget.tsx +11 -10
  83. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/page-header-widget.tsx +17 -16
  84. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/prose-section-widget.tsx +12 -11
  85. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/quote-widget.tsx +8 -7
  86. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/row-widget.tsx +14 -13
  87. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/section-intro-widget.tsx +13 -12
  88. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/signup-banner-widget.tsx +6 -5
  89. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/simple-action-list-widget.tsx +7 -6
  90. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/site-footer-widget.tsx +22 -12
  91. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/site-header-nav.tsx +9 -2
  92. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/site-header-widget.tsx +48 -24
  93. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/social-banner-widget.tsx +11 -7
  94. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/stats-widget.tsx +15 -11
  95. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/steps-widget.tsx +21 -20
  96. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/story-cards-widget.tsx +20 -16
  97. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/table-widget.tsx +8 -5
  98. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/tabs-widget.tsx +12 -8
  99. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/tags-widget.tsx +12 -9
  100. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/testimonial-widget.tsx +11 -7
  101. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/timeline-widget.tsx +22 -22
  102. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/under-construction-widget.tsx +3 -2
  103. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/video-widget.tsx +13 -12
  104. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/welcome-widget.tsx +5 -4
  105. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/endpoints/api/media_detail.py +10 -3
  106. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/endpoints/content_views.py +1 -1
  107. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/endpoints/public_views.py +20 -5
  108. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/endpoints/seo.py +9 -2
  109. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/endpoints/views.py +1 -1
  110. simple_module_pagebuilder-0.0.9/pagebuilder/fields/checkbox-field.tsx +57 -0
  111. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/fields/file-picker/file-gallery.tsx +12 -6
  112. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/fields/file-picker/image-picker-field.tsx +11 -7
  113. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/hooks/useAutosave.ts +4 -1
  114. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/hooks/useEditorForm.ts +4 -2
  115. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/hooks/useMediaDetail.ts +2 -1
  116. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/hooks/useMediaUploads.ts +5 -1
  117. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/hooks/usePageRevisions.ts +4 -2
  118. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/hooks/usePageSchedule.ts +8 -6
  119. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/hooks/usePageWorkflow.ts +13 -11
  120. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/hooks/useSnapshots.ts +5 -3
  121. simple_module_pagebuilder-0.0.9/pagebuilder/locales/en.json +1375 -0
  122. simple_module_pagebuilder-0.0.9/pagebuilder/media_files.py +259 -0
  123. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/media_service.py +24 -10
  124. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/media_usage.py +14 -8
  125. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/models/_layout.py +3 -3
  126. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/models/_media.py +15 -4
  127. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/models/_page.py +21 -13
  128. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/models/_redirect.py +7 -4
  129. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/models/_snapshot.py +6 -5
  130. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/module.py +40 -1
  131. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/pages/ContentImportReview.tsx +42 -32
  132. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/pages/ContentSnapshots.tsx +21 -13
  133. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/pages/LayoutEditor.tsx +43 -30
  134. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/pages/MediaDetail.tsx +36 -28
  135. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/pages/MediaLibrary.tsx +16 -14
  136. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/pages/PageEditor.tsx +11 -4
  137. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/pages/PageList.tsx +35 -29
  138. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/pages/PendingReview.tsx +26 -26
  139. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/pages/Trash.tsx +33 -27
  140. simple_module_pagebuilder-0.0.9/pagebuilder/scheduler.py +158 -0
  141. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/security.py +19 -4
  142. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/service/_trash.py +15 -5
  143. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/service/_workflow.py +29 -14
  144. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/snapshots/apply.py +1 -1
  145. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/snapshots/assets.py +10 -11
  146. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/snapshots/blobs.py +16 -0
  147. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/snapshots/capture.py +13 -5
  148. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/snapshots/media_match.py +4 -3
  149. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/snapshots/service.py +2 -3
  150. simple_module_pagebuilder-0.0.9/pagebuilder/tenancy.py +198 -0
  151. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/utils/editorSnapshot.ts +18 -5
  152. simple_module_pagebuilder-0.0.9/pagebuilder/utils/i18n.test.ts +137 -0
  153. simple_module_pagebuilder-0.0.9/pagebuilder/utils/i18n.ts +180 -0
  154. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/utils/mediaApi.ts +10 -2
  155. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/utils/request.ts +16 -4
  156. simple_module_pagebuilder-0.0.9/pagebuilder/utils/slugify.test.ts +46 -0
  157. simple_module_pagebuilder-0.0.9/pagebuilder/utils/slugify.ts +52 -0
  158. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pyproject.toml +11 -11
  159. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/conftest.py +35 -24
  160. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/db_fixture.py +6 -11
  161. simple_module_pagebuilder-0.0.9/tests/pg_support.py +54 -0
  162. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/snapshot_fixture.py +7 -14
  163. simple_module_pagebuilder-0.0.9/tests/tenant_app.py +64 -0
  164. simple_module_pagebuilder-0.0.9/tests/tenant_fixture.py +42 -0
  165. simple_module_pagebuilder-0.0.9/tests/test_i18n.py +77 -0
  166. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_image_processing.py +9 -22
  167. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_media_files.py +14 -18
  168. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_media_security.py +3 -15
  169. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_public_viewer.py +18 -0
  170. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_scheduled_publish.py +3 -11
  171. simple_module_pagebuilder-0.0.9/tests/test_scheduler_stop.py +81 -0
  172. simple_module_pagebuilder-0.0.9/tests/test_scheduler_tenancy.py +114 -0
  173. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_snapshot_apply.py +1 -1
  174. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_snapshot_apply_media.py +1 -1
  175. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_snapshot_capture.py +2 -2
  176. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_snapshot_media_match.py +1 -1
  177. simple_module_pagebuilder-0.0.9/tests/test_tenancy_blobs.py +42 -0
  178. simple_module_pagebuilder-0.0.9/tests/test_tenancy_core.py +177 -0
  179. simple_module_pagebuilder-0.0.9/tests/test_tenancy_isolation.py +85 -0
  180. simple_module_pagebuilder-0.0.9/tests/test_tenancy_media.py +245 -0
  181. simple_module_pagebuilder-0.0.9/tests/test_tenancy_public.py +125 -0
  182. simple_module_pagebuilder-0.0.9/tests/test_tenancy_routes.py +64 -0
  183. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tsconfig.json +1 -0
  184. simple_module_pagebuilder-0.0.7/pagebuilder/components/PageBoard.tsx +0 -127
  185. simple_module_pagebuilder-0.0.7/pagebuilder/components/widgets/call-to-action-widget.tsx +0 -83
  186. simple_module_pagebuilder-0.0.7/pagebuilder/components/widgets/contact-form-widget.tsx +0 -69
  187. simple_module_pagebuilder-0.0.7/pagebuilder/components/widgets/feature-cards-widget.tsx +0 -133
  188. simple_module_pagebuilder-0.0.7/pagebuilder/components/widgets/media-object-widget.tsx +0 -180
  189. simple_module_pagebuilder-0.0.7/pagebuilder/fields/checkbox-field.tsx +0 -22
  190. simple_module_pagebuilder-0.0.7/pagebuilder/media_files.py +0 -128
  191. simple_module_pagebuilder-0.0.7/pagebuilder/scheduler.py +0 -92
  192. simple_module_pagebuilder-0.0.7/pagebuilder/utils/slugify.ts +0 -9
  193. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/.gitignore +0 -0
  194. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/__init__.py +0 -0
  195. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/board.py +0 -0
  196. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/blockRegistry.test.ts +0 -0
  197. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/blockRegistry.ts +0 -0
  198. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/lazyBlock.tsx +0 -0
  199. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/media/types.ts +0 -0
  200. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/migrateContent.test.ts +0 -0
  201. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/migrateContent.ts +0 -0
  202. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/snapshots/planSummary.test.ts +0 -0
  203. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgetCatalog.test.tsx +0 -0
  204. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/_internal/accent-text.tsx +0 -0
  205. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/_internal/disclosure-chevron.tsx +0 -0
  206. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/_internal/eyebrow-split-section.tsx +0 -0
  207. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/_internal/link-arrow.tsx +0 -0
  208. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/_internal/rich-text.tsx +0 -0
  209. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/_internal/solid-icons.tsx +0 -0
  210. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/_shared/background-media.tsx +0 -0
  211. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/_shared/content-media.tsx +0 -0
  212. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/_shared/cta-button.tsx +0 -0
  213. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/_shared/empty-placeholder.tsx +0 -0
  214. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/_shared/eyebrow-text.tsx +0 -0
  215. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/_shared/heading.tsx +0 -0
  216. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/_shared/image-srcset.ts +0 -0
  217. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/_shared/index.ts +0 -0
  218. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/_shared/mask.ts +0 -0
  219. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/_shared/section.tsx +0 -0
  220. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/_shared/social-icon.tsx +0 -0
  221. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/_shared/text-link.tsx +0 -0
  222. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/article-cards-render.tsx +0 -0
  223. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/call-to-action-render.tsx +0 -0
  224. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/call-to-action-styles.ts +0 -0
  225. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/contact-form-render.tsx +0 -0
  226. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/divider-widget.test.tsx +0 -0
  227. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/faq-render.tsx +0 -0
  228. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/feature-cards-styles.ts +0 -0
  229. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/hero-widget-props.ts +0 -0
  230. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/media-object-layout.ts +0 -0
  231. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/media-object-render.tsx +0 -0
  232. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/media-object-text.tsx +0 -0
  233. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/timeline-layout.ts +0 -0
  234. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/components/widgets/timeline-render.tsx +0 -0
  235. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/contracts/__init__.py +0 -0
  236. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/contracts/events.py +0 -0
  237. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/contracts/schemas/__init__.py +0 -0
  238. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/contracts/schemas/_layout.py +0 -0
  239. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/contracts/schemas/_media.py +0 -0
  240. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/contracts/schemas/_pages.py +0 -0
  241. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/contracts/schemas/_snapshots.py +0 -0
  242. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/conversion/blocks-to-html.test.ts +0 -0
  243. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/conversion/blocks-to-html.ts +0 -0
  244. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/conversion/index.ts +0 -0
  245. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/conversion/types.ts +0 -0
  246. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/deps.py +0 -0
  247. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/diff.py +0 -0
  248. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/endpoints/__init__.py +0 -0
  249. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/endpoints/api/__init__.py +0 -0
  250. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/endpoints/api/_deps.py +0 -0
  251. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/endpoints/api/layout.py +0 -0
  252. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/endpoints/api/pages.py +0 -0
  253. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/endpoints/api/revisions.py +0 -0
  254. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/endpoints/api/snapshots.py +0 -0
  255. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/endpoints/api/uploads.py +0 -0
  256. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/endpoints/api/workflow.py +0 -0
  257. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/fields/file-picker/index.ts +0 -0
  258. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/fields/file-picker/types.ts +0 -0
  259. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/fields/index.ts +0 -0
  260. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/fields/media-adapter.ts +0 -0
  261. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/hooks/useIsNarrow.ts +0 -0
  262. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/hooks/usePendingDialog.ts +0 -0
  263. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/layout_service.py +0 -0
  264. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/locales.py +0 -0
  265. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/media_images.py +0 -0
  266. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/media_queries.py +0 -0
  267. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/models/__init__.py +0 -0
  268. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/models/_base.py +0 -0
  269. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/pages/PublicPage.tsx +0 -0
  270. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/permissions.py +0 -0
  271. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/public_claims.py +0 -0
  272. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/py.typed +0 -0
  273. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/redirects.py +0 -0
  274. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/service/__init__.py +0 -0
  275. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/service/_common.py +0 -0
  276. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/service/_revisions.py +0 -0
  277. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/service/_translations.py +0 -0
  278. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/services.py +0 -0
  279. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/settings.py +0 -0
  280. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/snapshots/__init__.py +0 -0
  281. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/snapshots/archive.py +0 -0
  282. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/snapshots/format.py +0 -0
  283. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/snapshots/pages.py +0 -0
  284. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/snapshots/plan.py +0 -0
  285. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/snapshots/validate.py +0 -0
  286. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/static/widgets-base.css +0 -0
  287. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/translation/apply.ts +0 -0
  288. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/translation/extract.ts +0 -0
  289. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/translation/index.ts +0 -0
  290. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/translation/translatable-fields.ts +0 -0
  291. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/translation/translation.test.ts +0 -0
  292. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/utils/api.ts +0 -0
  293. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/utils/blockOutline.test.ts +0 -0
  294. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/utils/blockOutline.ts +0 -0
  295. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/utils/datetime.ts +0 -0
  296. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/utils/decorative-image.ts +0 -0
  297. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/utils/locale.ts +0 -0
  298. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/utils/markdown.ts +0 -0
  299. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/utils/measure.ts +0 -0
  300. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/utils/mediaFormat.ts +0 -0
  301. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/utils/pagesApi.ts +0 -0
  302. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/utils/parse-list.ts +0 -0
  303. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/utils/request.test.ts +0 -0
  304. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/utils/snapshotsApi.ts +0 -0
  305. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/utils/types.ts +0 -0
  306. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/pagebuilder/utils/widgetUtils.ts +0 -0
  307. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/locale_fixture.py +0 -0
  308. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/page_helpers.py +0 -0
  309. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_admin_list_view.py +0 -0
  310. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_approval_workflow.py +0 -0
  311. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_auth_gating.py +0 -0
  312. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_csrf.py +0 -0
  313. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_draft_preview.py +0 -0
  314. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_hreflang_and_sitemap.py +0 -0
  315. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_media_detail.py +0 -0
  316. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_media_usage_escaping.py +0 -0
  317. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_module.py +0 -0
  318. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_multilingual.py +0 -0
  319. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_page_templates.py +0 -0
  320. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_page_translations.py +0 -0
  321. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_pages_api.py +0 -0
  322. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_pages_search.py +0 -0
  323. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_public_claims.py +0 -0
  324. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_public_routes.py +0 -0
  325. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_public_view_headers.py +0 -0
  326. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_redirects.py +0 -0
  327. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_revision_notes_and_diff.py +0 -0
  328. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_revisions_api.py +0 -0
  329. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_seo_meta.py +0 -0
  330. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_settings_source.py +0 -0
  331. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_site_layout.py +0 -0
  332. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_sitemap_robots.py +0 -0
  333. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_snapshot_archive.py +0 -0
  334. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_snapshot_assets.py +0 -0
  335. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_snapshot_blobs.py +0 -0
  336. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_snapshot_models.py +0 -0
  337. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_snapshot_multilingual.py +0 -0
  338. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_snapshot_page_payload.py +0 -0
  339. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_snapshot_plan.py +0 -0
  340. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_snapshot_validate.py +0 -0
  341. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_snapshot_views.py +0 -0
  342. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_snapshots_api.py +0 -0
  343. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_trash.py +0 -0
  344. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_trash_preconditions.py +0 -0
  345. {simple_module_pagebuilder-0.0.7 → simple_module_pagebuilder-0.0.9}/tests/test_uploads_api.py +0 -0
@@ -1,3 +1,27 @@
1
+ Metadata-Version: 2.5
2
+ Name: simple_module_pagebuilder
3
+ Version: 0.0.9
4
+ Summary: Drag-and-drop visual page builder for simple_module apps
5
+ Project-URL: Repository, https://github.com/antosubash/simple_module_python_modules
6
+ Author-email: Anto Subash <antosubash@live.com>
7
+ License-Expression: MIT
8
+ Keywords: cms,pagebuilder,puck,simple-module
9
+ Requires-Python: >=3.12
10
+ Requires-Dist: pillow>=10.0
11
+ Requires-Dist: pydantic-settings>=2.0
12
+ Requires-Dist: simple-module-core<0.1,>=0.0.35
13
+ Requires-Dist: simple-module-db<0.1,>=0.0.35
14
+ Requires-Dist: simple-module-hosting<0.1,>=0.0.35
15
+ Requires-Dist: simple-module-inertia<0.1,>=0.0.35
16
+ Requires-Dist: simple-module-settings<0.1,>=0.0.35
17
+ Requires-Dist: sqlalchemy>=2.0
18
+ Requires-Dist: sqlmodel>=0.0.21
19
+ Provides-Extra: dev
20
+ Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
21
+ Requires-Dist: pytest>=8.0; extra == 'dev'
22
+ Requires-Dist: simple-module-test<0.1,>=0.0.35; extra == 'dev'
23
+ Description-Content-Type: text/markdown
24
+
1
25
  # simple_module_pagebuilder
2
26
 
3
27
  Drag-and-drop visual page builder for [simple_module](https://github.com/antosubash/simple_module_python)
@@ -221,6 +245,64 @@ Its breadcrumb parent is the parent's own counterpart, so a trail never crosses
221
245
  languages. A page's own language is fixed for its lifetime — moving one would
222
246
  strand its slug and orphan the redirect pointing at it.
223
247
 
248
+ ## The editor's language
249
+
250
+ Separate from the page's. The section above is about what the *site*
251
+ publishes; this is about what the *editor* speaks, and the two are configured
252
+ in different places — `content_locales` for one, the host's
253
+ `SM_I18N_SUPPORTED_LOCALES` for the other.
254
+
255
+ Every editor string lives in `pagebuilder/locales/en.json`, registered by
256
+ `PagebuilderModule.locale_dirs()` under the `pagebuilder` namespace, so a key
257
+ reads `pagebuilder.<section>.<name>` in the merged catalogue the host ships to
258
+ the browser. Add a language by adding `pagebuilder/locales/<tag>.json` with the
259
+ same shape; the framework's `SM013`–`SM016` diagnostics report a file that has
260
+ drifted from the default.
261
+
262
+ The frontend derives its key tree from that JSON at compile time —
263
+ `pagebuilder/utils/i18n.ts` — rather than from the framework's generated
264
+ `keys`, which only carries the namespaces of modules that live in the
265
+ framework's own monorepo. The upshot is that `tsc` rejects a key the catalogue
266
+ does not define, and `pagebuilder/utils/i18n.test.ts` rejects an entry nothing
267
+ references, a plural missing a form, and a placeholder nothing fills.
268
+
269
+ **Block labels are keys, resolved at the screen.** A Puck config is a
270
+ module-scope constant — the palette is assembled before the app has rendered
271
+ anything — so a block cannot call a hook where its labels are written. What it
272
+ holds instead is the key, and `components/localizeConfig.ts` resolves the whole
273
+ assembled config once inside `PageEditor` and `LayoutEditor`: component labels,
274
+ field labels (including the ones nested in an `array` or `object` field),
275
+ select options, category titles and the viewport switcher. Because it walks the
276
+ *assembled* config, a block another module registered is localized on the same
277
+ pass, provided that module's labels are catalogue keys too.
278
+
279
+ `defaultProps` stay literal on purpose. They are the seed *content* a block is
280
+ inserted with and are then saved into the document, so translating them at
281
+ render time would rewrite what a visitor is served in whatever language the
282
+ author happened to be working in.
283
+
284
+ ## Multi-tenancy
285
+
286
+ Every pagebuilder table is tenant-owned (the framework's `MultiTenantMixin`),
287
+ so one host can run several sites. Slugs, redirects, media filenames and the
288
+ one-pending-import rule are unique **per tenant**, and each tenant has its own
289
+ site layout, media directory (`<media_root>/<tenant>/`) and snapshot blob store.
290
+
291
+ Which tenant a request acts for depends on the host:
292
+
293
+ - **Single-tenant** (`multi_tenant` off) — everything is tenant `"default"`,
294
+ where the migration also files every row that predates tenancy. A host that
295
+ pins `default_tenant` to anything else is refused at startup.
296
+ - **Multi-tenant** (`multi_tenant` on) — the tenant the framework resolved.
297
+ With the `tenants` module, anonymous visitors are resolved by subdomain
298
+ (`subdomain_base`); members by their membership. A public page, sitemap or
299
+ media request with no tenant answers 404 — the same as an unknown slug — and
300
+ an editor with no tenant gets 403. Custom domains are not supported yet.
301
+
302
+ The scheduler publishes due pages tenant by tenant, each in its own session.
303
+ Requires framework `0.0.35` or later, and the host migration that adds
304
+ `tenant_id` (`make migration` picks it up like any other model change).
305
+
224
306
  ## Content snapshots
225
307
 
226
308
  **Content › Import / Export** captures the site as a restore point. Every entry
@@ -1,26 +1,3 @@
1
- Metadata-Version: 2.5
2
- Name: simple_module_pagebuilder
3
- Version: 0.0.7
4
- Summary: Drag-and-drop visual page builder for simple_module apps
5
- Project-URL: Repository, https://github.com/antosubash/simple_module_python_modules
6
- Author-email: Anto Subash <antosubash@live.com>
7
- License-Expression: MIT
8
- Keywords: cms,pagebuilder,puck,simple-module
9
- Requires-Python: >=3.12
10
- Requires-Dist: pillow>=10.0
11
- Requires-Dist: pydantic-settings>=2.0
12
- Requires-Dist: simple-module-core<0.1,>=0.0.25
13
- Requires-Dist: simple-module-db<0.1,>=0.0.25
14
- Requires-Dist: simple-module-hosting<0.1,>=0.0.25
15
- Requires-Dist: simple-module-settings<0.1,>=0.0.25
16
- Requires-Dist: sqlalchemy>=2.0
17
- Requires-Dist: sqlmodel>=0.0.21
18
- Provides-Extra: dev
19
- Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
20
- Requires-Dist: pytest>=8.0; extra == 'dev'
21
- Requires-Dist: simple-module-test<0.1,>=0.0.25; extra == 'dev'
22
- Description-Content-Type: text/markdown
23
-
24
1
  # simple_module_pagebuilder
25
2
 
26
3
  Drag-and-drop visual page builder for [simple_module](https://github.com/antosubash/simple_module_python)
@@ -244,6 +221,64 @@ Its breadcrumb parent is the parent's own counterpart, so a trail never crosses
244
221
  languages. A page's own language is fixed for its lifetime — moving one would
245
222
  strand its slug and orphan the redirect pointing at it.
246
223
 
224
+ ## The editor's language
225
+
226
+ Separate from the page's. The section above is about what the *site*
227
+ publishes; this is about what the *editor* speaks, and the two are configured
228
+ in different places — `content_locales` for one, the host's
229
+ `SM_I18N_SUPPORTED_LOCALES` for the other.
230
+
231
+ Every editor string lives in `pagebuilder/locales/en.json`, registered by
232
+ `PagebuilderModule.locale_dirs()` under the `pagebuilder` namespace, so a key
233
+ reads `pagebuilder.<section>.<name>` in the merged catalogue the host ships to
234
+ the browser. Add a language by adding `pagebuilder/locales/<tag>.json` with the
235
+ same shape; the framework's `SM013`–`SM016` diagnostics report a file that has
236
+ drifted from the default.
237
+
238
+ The frontend derives its key tree from that JSON at compile time —
239
+ `pagebuilder/utils/i18n.ts` — rather than from the framework's generated
240
+ `keys`, which only carries the namespaces of modules that live in the
241
+ framework's own monorepo. The upshot is that `tsc` rejects a key the catalogue
242
+ does not define, and `pagebuilder/utils/i18n.test.ts` rejects an entry nothing
243
+ references, a plural missing a form, and a placeholder nothing fills.
244
+
245
+ **Block labels are keys, resolved at the screen.** A Puck config is a
246
+ module-scope constant — the palette is assembled before the app has rendered
247
+ anything — so a block cannot call a hook where its labels are written. What it
248
+ holds instead is the key, and `components/localizeConfig.ts` resolves the whole
249
+ assembled config once inside `PageEditor` and `LayoutEditor`: component labels,
250
+ field labels (including the ones nested in an `array` or `object` field),
251
+ select options, category titles and the viewport switcher. Because it walks the
252
+ *assembled* config, a block another module registered is localized on the same
253
+ pass, provided that module's labels are catalogue keys too.
254
+
255
+ `defaultProps` stay literal on purpose. They are the seed *content* a block is
256
+ inserted with and are then saved into the document, so translating them at
257
+ render time would rewrite what a visitor is served in whatever language the
258
+ author happened to be working in.
259
+
260
+ ## Multi-tenancy
261
+
262
+ Every pagebuilder table is tenant-owned (the framework's `MultiTenantMixin`),
263
+ so one host can run several sites. Slugs, redirects, media filenames and the
264
+ one-pending-import rule are unique **per tenant**, and each tenant has its own
265
+ site layout, media directory (`<media_root>/<tenant>/`) and snapshot blob store.
266
+
267
+ Which tenant a request acts for depends on the host:
268
+
269
+ - **Single-tenant** (`multi_tenant` off) — everything is tenant `"default"`,
270
+ where the migration also files every row that predates tenancy. A host that
271
+ pins `default_tenant` to anything else is refused at startup.
272
+ - **Multi-tenant** (`multi_tenant` on) — the tenant the framework resolved.
273
+ With the `tenants` module, anonymous visitors are resolved by subdomain
274
+ (`subdomain_base`); members by their membership. A public page, sitemap or
275
+ media request with no tenant answers 404 — the same as an unknown slug — and
276
+ an editor with no tenant gets 403. Custom domains are not supported yet.
277
+
278
+ The scheduler publishes due pages tenant by tenant, each in its own session.
279
+ Requires framework `0.0.35` or later, and the host migration that adds
280
+ `tenant_id` (`make migration` picks it up like any other model change).
281
+
247
282
  ## Content snapshots
248
283
 
249
284
  **Content › Import / Export** captures the site as a restore point. Every entry
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@simple-module-py/pagebuilder",
3
- "version": "0.0.7",
3
+ "version": "0.0.9",
4
4
  "private": true,
5
5
  "description": "Frontend assets for the PageBuilder module",
6
6
  "peerDependencies": {
7
7
  "react": "^19.0.0",
8
8
  "react-dom": "^19.0.0",
9
- "@inertiajs/react": "^2.0.0",
9
+ "@inertiajs/react": "^3.7.0",
10
10
  "@simple-module-py/ui": "*"
11
11
  },
12
12
  "devDependencies": {
@@ -28,8 +28,15 @@ import logging
28
28
  from fastapi import FastAPI
29
29
 
30
30
  from pagebuilder import locales
31
- from pagebuilder.media_files import MediaFiles, resolve_media_root, warn_on_orphaned_media
31
+ from pagebuilder.media_files import (
32
+ MediaFiles,
33
+ adopt_legacy_files,
34
+ is_generated_media_name,
35
+ resolve_media_root,
36
+ warn_on_orphaned_media,
37
+ )
32
38
  from pagebuilder.settings import PagebuilderSettings
39
+ from pagebuilder.snapshots.blobs import BLOBS_DIR, is_digest
33
40
 
34
41
  _log = logging.getLogger("simple_module.pagebuilder")
35
42
 
@@ -126,10 +133,21 @@ def mount_public_routers(app: FastAPI, settings: PagebuilderSettings) -> None:
126
133
 
127
134
 
128
135
  async def mount_media(app: FastAPI, settings: PagebuilderSettings) -> None:
129
- """Serve uploaded files from ``{media_url_prefix}/{filename}``."""
136
+ """Serve uploaded files from ``{media_url_prefix}/{tenant_id}/{filename}``.
137
+
138
+ Files (and snapshot blobs) written before per-tenant storage sit directly
139
+ under their root; they are moved into the default tenant's directory
140
+ first, so the orphan scan below and every later read find them (#38).
141
+ """
130
142
  media_root = resolve_media_root(settings.media_root)
131
143
  media_root.mkdir(parents=True, exist_ok=True)
132
144
  _log.info("pagebuilder.media_root: %s", media_root)
145
+ adopt_legacy_files(media_root, accept=is_generated_media_name)
146
+ adopt_legacy_files(
147
+ resolve_media_root(settings.snapshot_root) / BLOBS_DIR,
148
+ accept=is_digest,
149
+ label="snapshot_blobs",
150
+ )
133
151
  app.mount(
134
152
  settings.media_url_prefix,
135
153
  MediaFiles(directory=media_root),
@@ -14,6 +14,7 @@ import { Label } from '@simple-module-py/ui/components/ui/label';
14
14
  import { type ReactNode, useState } from 'react';
15
15
 
16
16
  import { usePendingDialog } from '../hooks/usePendingDialog';
17
+ import { keys, useT } from '../utils/i18n';
17
18
 
18
19
  /** How much a confirmation is allowed to cost the person clicking it.
19
20
  *
@@ -49,7 +50,7 @@ export function ConfirmDialog({
49
50
  trigger,
50
51
  title,
51
52
  description,
52
- confirmLabel = 'Confirm',
53
+ confirmLabel,
53
54
  destructive = false,
54
55
  level,
55
56
  confirmPhrase,
@@ -72,6 +73,8 @@ export function ConfirmDialog({
72
73
  /** Rejecting keeps the dialog open and surfaces the message. */
73
74
  onConfirm: () => Promise<unknown>;
74
75
  }) {
76
+ const { t } = useT();
77
+ const label = confirmLabel ?? t(keys.pagebuilder.confirm.confirm);
75
78
  const [typed, setTyped] = useState('');
76
79
 
77
80
  const resolvedLevel: ConfirmLevel = level ?? (destructive ? 'medium' : 'low');
@@ -87,8 +90,9 @@ export function ConfirmDialog({
87
90
  // phrase, because reopening must not inherit the one typed last time: that
88
91
  // would put a second delete one click from confirmed, which is the exact
89
92
  // property this level exists to remove.
90
- const { open, pending, error, change, run } = usePendingDialog(`${confirmLabel} failed`, () =>
91
- setTyped(''),
93
+ const { open, pending, error, change, run } = usePendingDialog(
94
+ t(keys.pagebuilder.confirm.failed, { action: label }),
95
+ () => setTyped(''),
92
96
  );
93
97
 
94
98
  return (
@@ -103,7 +107,9 @@ export function ConfirmDialog({
103
107
  {needsPhrase && (
104
108
  <div className="grid gap-2 py-2">
105
109
  <Label htmlFor={CONFIRM_PHRASE_INPUT}>
106
- Type <code className="font-mono font-semibold">{confirmPhrase}</code> to confirm
110
+ {t(keys.pagebuilder.confirm.type_prefix)}{' '}
111
+ <code className="font-mono font-semibold">{confirmPhrase}</code>{' '}
112
+ {t(keys.pagebuilder.confirm.type_suffix)}
107
113
  </Label>
108
114
  <Input
109
115
  id={CONFIRM_PHRASE_INPUT}
@@ -116,7 +122,9 @@ export function ConfirmDialog({
116
122
  )}
117
123
  {error && <p className="text-sm text-destructive">{error}</p>}
118
124
  <AlertDialogFooter>
119
- <AlertDialogCancel disabled={pending}>Cancel</AlertDialogCancel>
125
+ <AlertDialogCancel disabled={pending}>
126
+ {t(keys.pagebuilder.confirm.cancel)}
127
+ </AlertDialogCancel>
120
128
  <AlertDialogAction
121
129
  disabled={pending || !unlocked}
122
130
  className={
@@ -129,7 +137,7 @@ export function ConfirmDialog({
129
137
  void run(onConfirm);
130
138
  }}
131
139
  >
132
- {pending ? 'Working…' : confirmLabel}
140
+ {pending ? t(keys.pagebuilder.confirm.working) : label}
133
141
  </AlertDialogAction>
134
142
  </AlertDialogFooter>
135
143
  </AlertDialogContent>
@@ -1,5 +1,6 @@
1
1
  import type React from 'react';
2
2
  import type { RevisionDiff } from '../utils/api';
3
+ import { keys, useT } from '../utils/i18n';
3
4
 
4
5
  interface Props {
5
6
  diff: RevisionDiff;
@@ -23,6 +24,7 @@ function renderValue(value: unknown): string {
23
24
  * both sides can move together.
24
25
  */
25
26
  export function DiffSummary({ diff }: Props): React.JSX.Element {
27
+ const { t } = useT();
26
28
  const { metadata, blocks } = diff;
27
29
  const metaKeys = Object.keys(metadata);
28
30
  const totalChanges =
@@ -34,7 +36,7 @@ export function DiffSummary({ diff }: Props): React.JSX.Element {
34
36
  className="mt-3 rounded border bg-card p-3 text-xs text-muted-foreground"
35
37
  data-testid="diff-summary"
36
38
  >
37
- No changes between these revisions.
39
+ {t(keys.pagebuilder.diff.no_changes)}
38
40
  </div>
39
41
  );
40
42
  }
@@ -43,7 +45,7 @@ export function DiffSummary({ diff }: Props): React.JSX.Element {
43
45
  <div className="mt-3 space-y-2 rounded border bg-card p-3 text-xs" data-testid="diff-summary">
44
46
  {metaKeys.length > 0 && (
45
47
  <div>
46
- <div className="font-semibold">Metadata</div>
48
+ <div className="font-semibold">{t(keys.pagebuilder.diff.metadata)}</div>
47
49
  <ul className="ml-3 list-disc">
48
50
  {metaKeys.map((key) => (
49
51
  <li key={key}>
@@ -59,7 +61,9 @@ export function DiffSummary({ diff }: Props): React.JSX.Element {
59
61
  )}
60
62
  {blocks.added.length > 0 && (
61
63
  <div>
62
- <div className="font-semibold text-green-700">Added ({blocks.added.length})</div>
64
+ <div className="font-semibold text-green-700">
65
+ {t(keys.pagebuilder.diff.added, { count: blocks.added.length })}
66
+ </div>
63
67
  <ul className="ml-3 list-disc">
64
68
  {blocks.added.map((b) => (
65
69
  <li key={b.id}>
@@ -72,7 +76,9 @@ export function DiffSummary({ diff }: Props): React.JSX.Element {
72
76
  )}
73
77
  {blocks.removed.length > 0 && (
74
78
  <div>
75
- <div className="font-semibold text-red-700">Removed ({blocks.removed.length})</div>
79
+ <div className="font-semibold text-red-700">
80
+ {t(keys.pagebuilder.diff.removed, { count: blocks.removed.length })}
81
+ </div>
76
82
  <ul className="ml-3 list-disc">
77
83
  {blocks.removed.map((b) => (
78
84
  <li key={b.id}>
@@ -85,7 +91,9 @@ export function DiffSummary({ diff }: Props): React.JSX.Element {
85
91
  )}
86
92
  {blocks.changed.length > 0 && (
87
93
  <div>
88
- <div className="font-semibold text-amber-700">Changed ({blocks.changed.length})</div>
94
+ <div className="font-semibold text-amber-700">
95
+ {t(keys.pagebuilder.diff.changed, { count: blocks.changed.length })}
96
+ </div>
89
97
  <ul className="ml-3 list-disc">
90
98
  {blocks.changed.map((b) => (
91
99
  <li key={b.id}>
@@ -94,7 +102,8 @@ export function DiffSummary({ diff }: Props): React.JSX.Element {
94
102
  {b.type_before && (
95
103
  <span className="text-muted-foreground">
96
104
  {' '}
97
- — was <span className="font-mono">{b.type_before}</span>
105
+ {t(keys.pagebuilder.diff.was)}{' '}
106
+ <span className="font-mono">{b.type_before}</span>
98
107
  </span>
99
108
  )}
100
109
  {b.fields.length > 0 && <span>: {b.fields.join(', ')}</span>}
@@ -18,6 +18,7 @@ import {
18
18
  import { useEffect, useState } from 'react';
19
19
 
20
20
  import type { PageRead } from '../utils/api';
21
+ import { keys, useT } from '../utils/i18n';
21
22
  import { localeLabel, localePrefix } from '../utils/locale';
22
23
  import { createPage, listPages, listTemplates } from '../utils/pagesApi';
23
24
  import { slugify } from '../utils/slugify';
@@ -55,6 +56,7 @@ export function NewPageDialog({
55
56
  locales = ['en'],
56
57
  defaultLocale = 'en',
57
58
  }: Props) {
59
+ const { t } = useT();
58
60
  const [open, setOpen] = useState(false);
59
61
  const [title, setTitle] = useState('');
60
62
  // Null until the author edits it: while it is null the slug tracks the title,
@@ -124,7 +126,7 @@ export function NewPageDialog({
124
126
  return (
125
127
  <Dialog open={open} onOpenChange={reset}>
126
128
  <DialogTrigger asChild>
127
- <Button type="button">New page</Button>
129
+ <Button type="button">{t(keys.pagebuilder.new_page.trigger)}</Button>
128
130
  </DialogTrigger>
129
131
  <DialogContent>
130
132
  <form
@@ -134,28 +136,26 @@ export function NewPageDialog({
134
136
  }}
135
137
  >
136
138
  <DialogHeader>
137
- <DialogTitle>New page</DialogTitle>
138
- <DialogDescription>
139
- A few fields, all changeable later except the language. Creating opens the editor.
140
- </DialogDescription>
139
+ <DialogTitle>{t(keys.pagebuilder.new_page.title)}</DialogTitle>
140
+ <DialogDescription>{t(keys.pagebuilder.new_page.description)}</DialogDescription>
141
141
  </DialogHeader>
142
142
 
143
143
  <div className="grid gap-4 py-4">
144
144
  <div className="grid gap-2">
145
- <Label htmlFor={TITLE_ID}>Title</Label>
145
+ <Label htmlFor={TITLE_ID}>{t(keys.pagebuilder.new_page.title_label)}</Label>
146
146
  <Input
147
147
  id={TITLE_ID}
148
148
  value={title}
149
149
  autoFocus
150
150
  disabled={pending}
151
- placeholder="Field methods"
151
+ placeholder={t(keys.pagebuilder.new_page.title_placeholder)}
152
152
  onChange={(e) => setTitle(e.target.value)}
153
153
  />
154
154
  </div>
155
155
 
156
156
  {locales.length > 1 && (
157
157
  <div className="grid gap-2">
158
- <Label htmlFor={LOCALE_ID}>Language</Label>
158
+ <Label htmlFor={LOCALE_ID}>{t(keys.pagebuilder.new_page.language_label)}</Label>
159
159
  <NativeSelect
160
160
  id={LOCALE_ID}
161
161
  value={locale}
@@ -176,14 +176,13 @@ export function NewPageDialog({
176
176
  ))}
177
177
  </NativeSelect>
178
178
  <p className="text-xs text-muted-foreground">
179
- Fixed once the page exists. To publish the same page in another language, add a
180
- translation from the editor's Languages tab.
179
+ {t(keys.pagebuilder.new_page.language_help)}
181
180
  </p>
182
181
  </div>
183
182
  )}
184
183
 
185
184
  <div className="grid gap-2">
186
- <Label htmlFor={SLUG_ID}>URL</Label>
185
+ <Label htmlFor={SLUG_ID}>{t(keys.pagebuilder.new_page.url_label)}</Label>
187
186
  <div className="flex items-center gap-1">
188
187
  <span className="text-sm text-muted-foreground">
189
188
  {localePrefix(locale, defaultLocale)}
@@ -199,16 +198,16 @@ export function NewPageDialog({
199
198
  </div>
200
199
 
201
200
  <div className="grid gap-2">
202
- <Label htmlFor={START_ID}>Start from</Label>
201
+ <Label htmlFor={START_ID}>{t(keys.pagebuilder.new_page.start_label)}</Label>
203
202
  <NativeSelect
204
203
  id={START_ID}
205
204
  value={startFrom}
206
205
  disabled={pending}
207
206
  onChange={(e) => setStartFrom(e.target.value)}
208
207
  >
209
- <option value={BLANK}>Blank</option>
208
+ <option value={BLANK}>{t(keys.pagebuilder.new_page.start_blank)}</option>
210
209
  {templates.length > 0 && (
211
- <NativeSelectOptGroup label="Templates">
210
+ <NativeSelectOptGroup label={t(keys.pagebuilder.new_page.start_templates)}>
212
211
  {templates.map((t) => (
213
212
  <option key={t.id} value={String(t.id)}>
214
213
  {t.title}
@@ -217,7 +216,7 @@ export function NewPageDialog({
217
216
  </NativeSelectOptGroup>
218
217
  )}
219
218
  {copyable.length > 0 && (
220
- <NativeSelectOptGroup label="Copy a page">
219
+ <NativeSelectOptGroup label={t(keys.pagebuilder.new_page.start_copy)}>
221
220
  {copyable.map((p) => (
222
221
  <option key={p.id} value={String(p.id)}>
223
222
  {p.title}
@@ -227,20 +226,19 @@ export function NewPageDialog({
227
226
  )}
228
227
  </NativeSelect>
229
228
  <p className="text-xs text-muted-foreground">
230
- Templates are ordinary pages flagged as templates, so the set grows without a
231
- developer.
229
+ {t(keys.pagebuilder.new_page.start_help)}
232
230
  </p>
233
231
  </div>
234
232
 
235
233
  <div className="grid gap-2">
236
- <Label htmlFor={PARENT_ID}>Parent</Label>
234
+ <Label htmlFor={PARENT_ID}>{t(keys.pagebuilder.new_page.parent_label)}</Label>
237
235
  <NativeSelect
238
236
  id={PARENT_ID}
239
237
  value={parentId}
240
238
  disabled={pending}
241
239
  onChange={(e) => setParentId(e.target.value)}
242
240
  >
243
- <option value="">None</option>
241
+ <option value="">{t(keys.pagebuilder.new_page.parent_none)}</option>
244
242
  {pages
245
243
  .filter((p) => p.locale === locale)
246
244
  .map((p) => (
@@ -250,8 +248,7 @@ export function NewPageDialog({
250
248
  ))}
251
249
  </NativeSelect>
252
250
  <p className="text-xs text-muted-foreground">
253
- Optional. Affects the breadcrumb, not the URL. Only pages in the same language — a
254
- breadcrumb that crosses languages sends a reader out of theirs.
251
+ {t(keys.pagebuilder.new_page.parent_help)}
255
252
  </p>
256
253
  </div>
257
254
 
@@ -260,10 +257,12 @@ export function NewPageDialog({
260
257
 
261
258
  <DialogFooter>
262
259
  <Button type="button" variant="outline" disabled={pending} onClick={() => reset(false)}>
263
- Cancel
260
+ {t(keys.pagebuilder.new_page.cancel)}
264
261
  </Button>
265
262
  <Button type="submit" disabled={pending || !title.trim() || !slug}>
266
- {pending ? 'Creating…' : 'Create and open editor'}
263
+ {pending
264
+ ? t(keys.pagebuilder.new_page.creating)
265
+ : t(keys.pagebuilder.new_page.create)}
267
266
  </Button>
268
267
  </DialogFooter>
269
268
  </form>
@@ -13,6 +13,7 @@ import { Textarea } from '@simple-module-py/ui/components/ui/textarea';
13
13
  import { type ReactNode, useId, useState } from 'react';
14
14
 
15
15
  import { usePendingDialog } from '../hooks/usePendingDialog';
16
+ import { keys, useT } from '../utils/i18n';
16
17
 
17
18
  /**
18
19
  * Collect a note — a rejection reason, a publish message — before running an
@@ -47,13 +48,15 @@ export function NoteDialog({
47
48
  /** Rejecting keeps the dialog open and surfaces the message. */
48
49
  onSubmit: (note: string) => Promise<unknown>;
49
50
  }) {
51
+ const { t } = useT();
50
52
  const fieldId = useId();
51
53
  const [note, setNote] = useState('');
52
54
  // The open/pending/error lifecycle is shared with ConfirmDialog — see the
53
55
  // hook. The note clears on every close path so a reopened dialog starts
54
56
  // blank rather than carrying a half-typed message.
55
- const { open, pending, error, change, run } = usePendingDialog(`${submitLabel} failed`, () =>
56
- setNote(''),
57
+ const { open, pending, error, change, run } = usePendingDialog(
58
+ t(keys.pagebuilder.confirm.failed, { action: submitLabel }),
59
+ () => setNote(''),
57
60
  );
58
61
 
59
62
  const submit = () => {
@@ -79,7 +82,11 @@ export function NoteDialog({
79
82
  <div className="grid gap-2 py-4">
80
83
  <Label htmlFor={fieldId}>
81
84
  {label}
82
- {!required && <span className="ml-1 text-muted-foreground">(optional)</span>}
85
+ {!required && (
86
+ <span className="ml-1 text-muted-foreground">
87
+ {t(keys.pagebuilder.confirm.optional)}
88
+ </span>
89
+ )}
83
90
  </Label>
84
91
  <Textarea
85
92
  id={fieldId}
@@ -99,14 +106,14 @@ export function NoteDialog({
99
106
  disabled={pending}
100
107
  onClick={() => change(false)}
101
108
  >
102
- Cancel
109
+ {t(keys.pagebuilder.confirm.cancel)}
103
110
  </Button>
104
111
  <Button
105
112
  type="submit"
106
113
  variant={destructive ? 'destructive' : 'default'}
107
114
  disabled={pending || (required && !note.trim())}
108
115
  >
109
- {pending ? 'Working…' : submitLabel}
116
+ {pending ? t(keys.pagebuilder.confirm.working) : submitLabel}
110
117
  </Button>
111
118
  </DialogFooter>
112
119
  </form>