@rakun-kit/manager-react 1.5.9 → 1.6.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.
Files changed (318) hide show
  1. package/README.md +366 -297
  2. package/dist/cjs/app/runtime-app.js +4 -1
  3. package/dist/cjs/app/runtime-app.js.map +1 -1
  4. package/dist/cjs/components/app-sidebar.js +13 -2
  5. package/dist/cjs/components/app-sidebar.js.map +1 -1
  6. package/dist/cjs/components/media/MediaLibrary.js +10 -1
  7. package/dist/cjs/components/media/MediaLibrary.js.map +1 -1
  8. package/dist/cjs/components/media/contexts/MediaLibraryContext.js +1 -1
  9. package/dist/cjs/components/media/contexts/MediaLibraryContext.js.map +1 -1
  10. package/dist/cjs/components/media/previews/MediaContextMenuContent.js +68 -15
  11. package/dist/cjs/components/media/previews/MediaContextMenuContent.js.map +1 -1
  12. package/dist/cjs/components/media/previews/Previews.js +89 -35
  13. package/dist/cjs/components/media/previews/Previews.js.map +1 -1
  14. package/dist/cjs/components/media/previews/context/MediaPreviewContext.js.map +1 -1
  15. package/dist/cjs/components/media/previews/dialogs/ExpandedPreviewDialog.js +7 -10
  16. package/dist/cjs/components/media/previews/dialogs/ExpandedPreviewDialog.js.map +1 -1
  17. package/dist/cjs/components/media/previews/hooks/useMediaPreviewRenderer.js +3 -1
  18. package/dist/cjs/components/media/previews/hooks/useMediaPreviewRenderer.js.map +1 -1
  19. package/dist/cjs/components/media/previews/toolbar/PreviewsToolbar.js +16 -9
  20. package/dist/cjs/components/media/previews/toolbar/PreviewsToolbar.js.map +1 -1
  21. package/dist/cjs/components/media/previews/utils/mediaDownload.js +54 -0
  22. package/dist/cjs/components/media/previews/utils/mediaDownload.js.map +1 -0
  23. package/dist/cjs/components/media/previews/views/PreviewsListView.js +1 -1
  24. package/dist/cjs/components/media/previews/views/PreviewsListView.js.map +1 -1
  25. package/dist/cjs/components/rakun-logo.js +4 -9
  26. package/dist/cjs/components/rakun-logo.js.map +1 -1
  27. package/dist/cjs/components/ui/context-menu.js +1 -1
  28. package/dist/cjs/components/ui/context-menu.js.map +1 -1
  29. package/dist/cjs/i18n/catalog.js +366 -6
  30. package/dist/cjs/i18n/catalog.js.map +1 -1
  31. package/dist/cjs/layouts.js +2 -2
  32. package/dist/cjs/layouts.js.map +1 -1
  33. package/dist/cjs/lib/media.js +1 -0
  34. package/dist/cjs/lib/media.js.map +1 -1
  35. package/dist/cjs/media.js +45 -0
  36. package/dist/cjs/media.js.map +1 -1
  37. package/dist/cjs/router/dashboard/[contentType]/[edit]/ContentTypeEdit.js +15 -4
  38. package/dist/cjs/router/dashboard/[contentType]/[edit]/ContentTypeEdit.js.map +1 -1
  39. package/dist/cjs/router/dashboard/[contentType]/[edit]/_components/ContentCommentsDrawer.js +11 -6
  40. package/dist/cjs/router/dashboard/[contentType]/[edit]/_components/ContentCommentsDrawer.js.map +1 -1
  41. package/dist/cjs/router/dashboard/[contentType]/[edit]/_components/EditTabPanels.js +2 -1
  42. package/dist/cjs/router/dashboard/[contentType]/[edit]/_components/EditTabPanels.js.map +1 -1
  43. package/dist/cjs/router/dashboard/[contentType]/[edit]/_components/EditToolbar.js +3 -2
  44. package/dist/cjs/router/dashboard/[contentType]/[edit]/_components/EditToolbar.js.map +1 -1
  45. package/dist/cjs/router/dashboard/[contentType]/[edit]/_components/PreviewPanel.js +1 -1
  46. package/dist/cjs/router/dashboard/[contentType]/[edit]/_components/PreviewPanel.js.map +1 -1
  47. package/dist/cjs/router/dashboard/[contentType]/[edit]/_components/SeoTabContent.js +290 -0
  48. package/dist/cjs/router/dashboard/[contentType]/[edit]/_components/SeoTabContent.js.map +1 -0
  49. package/dist/cjs/router/dashboard/[contentType]/[edit]/_components/seo-analysis.js +88 -0
  50. package/dist/cjs/router/dashboard/[contentType]/[edit]/_components/seo-analysis.js.map +1 -0
  51. package/dist/cjs/router/dashboard/[contentType]/[edit]/_context/EditPageContext.js +9 -1
  52. package/dist/cjs/router/dashboard/[contentType]/[edit]/_context/EditPageContext.js.map +1 -1
  53. package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/ContentReferenceField/ContentReferenceMultiSelectUI.js +15 -2
  54. package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/ContentReferenceField/ContentReferenceMultiSelectUI.js.map +1 -1
  55. package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/DynamicDataControl.js +222 -232
  56. package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/DynamicDataControl.js.map +1 -1
  57. package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/FileField/index.js +20 -1
  58. package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/FileField/index.js.map +1 -1
  59. package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/LinkField/LinkUI.js +27 -21
  60. package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/LinkField/LinkUI.js.map +1 -1
  61. package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/LinkField/index.js.map +1 -1
  62. package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/LinkField/linkValue.js +25 -0
  63. package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/LinkField/linkValue.js.map +1 -0
  64. package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/ListField/IteratorModulePicker.js +10 -1
  65. package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/ListField/IteratorModulePicker.js.map +1 -1
  66. package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/ListField/SimpleListUI.js +38 -11
  67. package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/ListField/SimpleListUI.js.map +1 -1
  68. package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/MenuField/MenuUI.js +135 -0
  69. package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/MenuField/MenuUI.js.map +1 -0
  70. package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/MenuField/index.js +10 -0
  71. package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/MenuField/index.js.map +1 -0
  72. package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/MenuField/menuTree.js +113 -0
  73. package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/MenuField/menuTree.js.map +1 -0
  74. package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/Select/MultiSelectUI.js +15 -2
  75. package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/Select/MultiSelectUI.js.map +1 -1
  76. package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/shared/ItemLimitStatus.js +22 -0
  77. package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/shared/ItemLimitStatus.js.map +1 -0
  78. package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/shared/index.js.map +1 -1
  79. package/dist/cjs/router/dashboard/[contentType]/[edit]/_hooks/useContentDocumentActions.js +2 -0
  80. package/dist/cjs/router/dashboard/[contentType]/[edit]/_hooks/useContentDocumentActions.js.map +1 -1
  81. package/dist/cjs/router/dashboard/[contentType]/[edit]/_hooks/useContentPreview.js +198 -0
  82. package/dist/cjs/router/dashboard/[contentType]/[edit]/_hooks/useContentPreview.js.map +1 -1
  83. package/dist/cjs/router/dashboard/[contentType]/[edit]/edit.js +10 -1
  84. package/dist/cjs/router/dashboard/[contentType]/[edit]/edit.js.map +1 -1
  85. package/dist/cjs/router/dashboard/[contentType]/[edit]/screen.js +2 -2
  86. package/dist/cjs/router/dashboard/[contentType]/[edit]/screen.js.map +1 -1
  87. package/dist/cjs/router/dashboard/debugging/api-routes/ApiTest.js +2 -2
  88. package/dist/cjs/router/dashboard/debugging/api-routes/ApiTest.js.map +1 -1
  89. package/dist/cjs/router/dashboard/debugging/api-routes/JsonViewer.js +17 -0
  90. package/dist/cjs/router/dashboard/debugging/api-routes/JsonViewer.js.map +1 -0
  91. package/dist/cjs/router/dashboard/debugging/api-routes/SchemaViewer.js +40 -26
  92. package/dist/cjs/router/dashboard/debugging/api-routes/SchemaViewer.js.map +1 -1
  93. package/dist/cjs/router/dashboard/debugging/api-routes/test.js +6 -5
  94. package/dist/cjs/router/dashboard/debugging/api-routes/test.js.map +1 -1
  95. package/dist/cjs/router/dashboard/seo/index.js +6 -0
  96. package/dist/cjs/router/dashboard/seo/index.js.map +1 -0
  97. package/dist/cjs/router/dashboard/seo/screen.js +219 -0
  98. package/dist/cjs/router/dashboard/seo/screen.js.map +1 -0
  99. package/dist/cjs/router/dashboard/seo/site-analysis.js +153 -0
  100. package/dist/cjs/router/dashboard/seo/site-analysis.js.map +1 -0
  101. package/dist/cjs/router/dashboard/settings/llms/index.js +6 -0
  102. package/dist/cjs/router/dashboard/settings/llms/index.js.map +1 -0
  103. package/dist/cjs/router/dashboard/settings/llms/screen.js +122 -0
  104. package/dist/cjs/router/dashboard/settings/llms/screen.js.map +1 -0
  105. package/dist/cjs/router/dashboard/settings/screen.js +7 -0
  106. package/dist/cjs/router/dashboard/settings/screen.js.map +1 -1
  107. package/dist/cjs/router/shared/route-definitions.js +3 -2
  108. package/dist/cjs/router/shared/route-definitions.js.map +1 -1
  109. package/dist/cjs/router/shared/route-list.js +19 -3
  110. package/dist/cjs/router/shared/route-list.js.map +1 -1
  111. package/dist/cjs/router/shared/route-renderer.js +2 -1
  112. package/dist/cjs/router/shared/route-renderer.js.map +1 -1
  113. package/dist/docs/index.md +294 -192
  114. package/dist/esm/app/runtime-app.d.ts.map +1 -1
  115. package/dist/esm/app/runtime-app.js +4 -1
  116. package/dist/esm/app/runtime-app.js.map +1 -1
  117. package/dist/esm/components/app-sidebar.d.ts +2 -1
  118. package/dist/esm/components/app-sidebar.d.ts.map +1 -1
  119. package/dist/esm/components/app-sidebar.js +15 -4
  120. package/dist/esm/components/app-sidebar.js.map +1 -1
  121. package/dist/esm/components/media/MediaLibrary.d.ts.map +1 -1
  122. package/dist/esm/components/media/MediaLibrary.js +11 -2
  123. package/dist/esm/components/media/MediaLibrary.js.map +1 -1
  124. package/dist/esm/components/media/contexts/MediaLibraryContext.d.ts +2 -0
  125. package/dist/esm/components/media/contexts/MediaLibraryContext.d.ts.map +1 -1
  126. package/dist/esm/components/media/contexts/MediaLibraryContext.js +1 -1
  127. package/dist/esm/components/media/contexts/MediaLibraryContext.js.map +1 -1
  128. package/dist/esm/components/media/previews/MediaContextMenuContent.d.ts.map +1 -1
  129. package/dist/esm/components/media/previews/MediaContextMenuContent.js +70 -17
  130. package/dist/esm/components/media/previews/MediaContextMenuContent.js.map +1 -1
  131. package/dist/esm/components/media/previews/Previews.d.ts.map +1 -1
  132. package/dist/esm/components/media/previews/Previews.js +90 -36
  133. package/dist/esm/components/media/previews/Previews.js.map +1 -1
  134. package/dist/esm/components/media/previews/context/MediaPreviewContext.d.ts +2 -0
  135. package/dist/esm/components/media/previews/context/MediaPreviewContext.d.ts.map +1 -1
  136. package/dist/esm/components/media/previews/context/MediaPreviewContext.js.map +1 -1
  137. package/dist/esm/components/media/previews/dialogs/ExpandedPreviewDialog.d.ts.map +1 -1
  138. package/dist/esm/components/media/previews/dialogs/ExpandedPreviewDialog.js +7 -10
  139. package/dist/esm/components/media/previews/dialogs/ExpandedPreviewDialog.js.map +1 -1
  140. package/dist/esm/components/media/previews/hooks/useMediaPreviewRenderer.d.ts.map +1 -1
  141. package/dist/esm/components/media/previews/hooks/useMediaPreviewRenderer.js +3 -1
  142. package/dist/esm/components/media/previews/hooks/useMediaPreviewRenderer.js.map +1 -1
  143. package/dist/esm/components/media/previews/toolbar/PreviewsToolbar.d.ts +4 -1
  144. package/dist/esm/components/media/previews/toolbar/PreviewsToolbar.d.ts.map +1 -1
  145. package/dist/esm/components/media/previews/toolbar/PreviewsToolbar.js +17 -10
  146. package/dist/esm/components/media/previews/toolbar/PreviewsToolbar.js.map +1 -1
  147. package/dist/esm/components/media/previews/utils/mediaDownload.d.ts +13 -0
  148. package/dist/esm/components/media/previews/utils/mediaDownload.d.ts.map +1 -0
  149. package/dist/esm/components/media/previews/utils/mediaDownload.js +49 -0
  150. package/dist/esm/components/media/previews/utils/mediaDownload.js.map +1 -0
  151. package/dist/esm/components/media/previews/views/PreviewsListView.js +1 -1
  152. package/dist/esm/components/media/previews/views/PreviewsListView.js.map +1 -1
  153. package/dist/esm/components/rakun-logo.d.ts +1 -5
  154. package/dist/esm/components/rakun-logo.d.ts.map +1 -1
  155. package/dist/esm/components/rakun-logo.js +1 -6
  156. package/dist/esm/components/rakun-logo.js.map +1 -1
  157. package/dist/esm/components/ui/context-menu.js +1 -1
  158. package/dist/esm/components/ui/context-menu.js.map +1 -1
  159. package/dist/esm/i18n/catalog.d.ts +645 -6
  160. package/dist/esm/i18n/catalog.d.ts.map +1 -1
  161. package/dist/esm/i18n/catalog.js +366 -6
  162. package/dist/esm/i18n/catalog.js.map +1 -1
  163. package/dist/esm/layouts.d.ts +3 -1
  164. package/dist/esm/layouts.d.ts.map +1 -1
  165. package/dist/esm/layouts.js +2 -2
  166. package/dist/esm/layouts.js.map +1 -1
  167. package/dist/esm/lib/media.d.ts +8 -0
  168. package/dist/esm/lib/media.d.ts.map +1 -1
  169. package/dist/esm/lib/media.js +1 -0
  170. package/dist/esm/lib/media.js.map +1 -1
  171. package/dist/esm/media.d.ts +19 -1
  172. package/dist/esm/media.d.ts.map +1 -1
  173. package/dist/esm/media.js +44 -0
  174. package/dist/esm/media.js.map +1 -1
  175. package/dist/esm/router/dashboard/[contentType]/[edit]/ContentTypeEdit.d.ts.map +1 -1
  176. package/dist/esm/router/dashboard/[contentType]/[edit]/ContentTypeEdit.js +18 -7
  177. package/dist/esm/router/dashboard/[contentType]/[edit]/ContentTypeEdit.js.map +1 -1
  178. package/dist/esm/router/dashboard/[contentType]/[edit]/_components/ContentCommentsDrawer.d.ts.map +1 -1
  179. package/dist/esm/router/dashboard/[contentType]/[edit]/_components/ContentCommentsDrawer.js +11 -6
  180. package/dist/esm/router/dashboard/[contentType]/[edit]/_components/ContentCommentsDrawer.js.map +1 -1
  181. package/dist/esm/router/dashboard/[contentType]/[edit]/_components/EditTabPanels.d.ts.map +1 -1
  182. package/dist/esm/router/dashboard/[contentType]/[edit]/_components/EditTabPanels.js +2 -1
  183. package/dist/esm/router/dashboard/[contentType]/[edit]/_components/EditTabPanels.js.map +1 -1
  184. package/dist/esm/router/dashboard/[contentType]/[edit]/_components/EditToolbar.d.ts.map +1 -1
  185. package/dist/esm/router/dashboard/[contentType]/[edit]/_components/EditToolbar.js +4 -3
  186. package/dist/esm/router/dashboard/[contentType]/[edit]/_components/EditToolbar.js.map +1 -1
  187. package/dist/esm/router/dashboard/[contentType]/[edit]/_components/PreviewPanel.d.ts.map +1 -1
  188. package/dist/esm/router/dashboard/[contentType]/[edit]/_components/PreviewPanel.js +1 -1
  189. package/dist/esm/router/dashboard/[contentType]/[edit]/_components/PreviewPanel.js.map +1 -1
  190. package/dist/esm/router/dashboard/[contentType]/[edit]/_components/SeoTabContent.d.ts +2 -0
  191. package/dist/esm/router/dashboard/[contentType]/[edit]/_components/SeoTabContent.d.ts.map +1 -0
  192. package/dist/esm/router/dashboard/[contentType]/[edit]/_components/SeoTabContent.js +283 -0
  193. package/dist/esm/router/dashboard/[contentType]/[edit]/_components/SeoTabContent.js.map +1 -0
  194. package/dist/esm/router/dashboard/[contentType]/[edit]/_components/seo-analysis.d.ts +10 -0
  195. package/dist/esm/router/dashboard/[contentType]/[edit]/_components/seo-analysis.d.ts.map +1 -0
  196. package/dist/esm/router/dashboard/[contentType]/[edit]/_components/seo-analysis.js +83 -0
  197. package/dist/esm/router/dashboard/[contentType]/[edit]/_components/seo-analysis.js.map +1 -0
  198. package/dist/esm/router/dashboard/[contentType]/[edit]/_context/EditPageContext.d.ts +2 -1
  199. package/dist/esm/router/dashboard/[contentType]/[edit]/_context/EditPageContext.d.ts.map +1 -1
  200. package/dist/esm/router/dashboard/[contentType]/[edit]/_context/EditPageContext.js +9 -1
  201. package/dist/esm/router/dashboard/[contentType]/[edit]/_context/EditPageContext.js.map +1 -1
  202. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/ContentReferenceField/ContentReferenceMultiSelectUI.d.ts.map +1 -1
  203. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/ContentReferenceField/ContentReferenceMultiSelectUI.js +15 -2
  204. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/ContentReferenceField/ContentReferenceMultiSelectUI.js.map +1 -1
  205. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/DynamicDataControl.d.ts +6 -2
  206. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/DynamicDataControl.d.ts.map +1 -1
  207. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/DynamicDataControl.js +221 -234
  208. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/DynamicDataControl.js.map +1 -1
  209. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/FileField/index.d.ts.map +1 -1
  210. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/FileField/index.js +20 -1
  211. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/FileField/index.js.map +1 -1
  212. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/LinkField/LinkUI.d.ts.map +1 -1
  213. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/LinkField/LinkUI.js +27 -21
  214. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/LinkField/LinkUI.js.map +1 -1
  215. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/LinkField/index.d.ts +4 -1
  216. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/LinkField/index.d.ts.map +1 -1
  217. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/LinkField/index.js.map +1 -1
  218. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/LinkField/linkValue.d.ts +4 -0
  219. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/LinkField/linkValue.d.ts.map +1 -0
  220. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/LinkField/linkValue.js +21 -0
  221. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/LinkField/linkValue.js.map +1 -0
  222. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/ListField/IteratorModulePicker.d.ts.map +1 -1
  223. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/ListField/IteratorModulePicker.js +11 -2
  224. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/ListField/IteratorModulePicker.js.map +1 -1
  225. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/ListField/SimpleListUI.d.ts.map +1 -1
  226. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/ListField/SimpleListUI.js +38 -11
  227. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/ListField/SimpleListUI.js.map +1 -1
  228. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/MenuField/MenuUI.d.ts +4 -0
  229. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/MenuField/MenuUI.d.ts.map +1 -0
  230. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/MenuField/MenuUI.js +130 -0
  231. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/MenuField/MenuUI.js.map +1 -0
  232. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/MenuField/index.d.ts +14 -0
  233. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/MenuField/index.d.ts.map +1 -0
  234. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/MenuField/index.js +5 -0
  235. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/MenuField/index.js.map +1 -0
  236. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/MenuField/menuTree.d.ts +23 -0
  237. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/MenuField/menuTree.d.ts.map +1 -0
  238. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/MenuField/menuTree.js +103 -0
  239. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/MenuField/menuTree.js.map +1 -0
  240. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/Select/MultiSelectUI.d.ts.map +1 -1
  241. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/Select/MultiSelectUI.js +15 -2
  242. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/Select/MultiSelectUI.js.map +1 -1
  243. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/shared/ItemLimitStatus.d.ts +6 -0
  244. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/shared/ItemLimitStatus.d.ts.map +1 -0
  245. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/shared/ItemLimitStatus.js +18 -0
  246. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/shared/ItemLimitStatus.js.map +1 -0
  247. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/shared/index.d.ts +2 -1
  248. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/shared/index.d.ts.map +1 -1
  249. package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/shared/index.js.map +1 -1
  250. package/dist/esm/router/dashboard/[contentType]/[edit]/_hooks/useContentDocumentActions.d.ts.map +1 -1
  251. package/dist/esm/router/dashboard/[contentType]/[edit]/_hooks/useContentDocumentActions.js +2 -0
  252. package/dist/esm/router/dashboard/[contentType]/[edit]/_hooks/useContentDocumentActions.js.map +1 -1
  253. package/dist/esm/router/dashboard/[contentType]/[edit]/_hooks/useContentPreview.d.ts +43 -0
  254. package/dist/esm/router/dashboard/[contentType]/[edit]/_hooks/useContentPreview.d.ts.map +1 -1
  255. package/dist/esm/router/dashboard/[contentType]/[edit]/_hooks/useContentPreview.js +198 -0
  256. package/dist/esm/router/dashboard/[contentType]/[edit]/_hooks/useContentPreview.js.map +1 -1
  257. package/dist/esm/router/dashboard/[contentType]/[edit]/_hooks/useRouteLayoutData.d.ts.map +1 -1
  258. package/dist/esm/router/dashboard/[contentType]/[edit]/edit.d.ts.map +1 -1
  259. package/dist/esm/router/dashboard/[contentType]/[edit]/edit.js +10 -1
  260. package/dist/esm/router/dashboard/[contentType]/[edit]/edit.js.map +1 -1
  261. package/dist/esm/router/dashboard/[contentType]/[edit]/edit.types.d.ts +1 -0
  262. package/dist/esm/router/dashboard/[contentType]/[edit]/edit.types.d.ts.map +1 -1
  263. package/dist/esm/router/dashboard/[contentType]/[edit]/screen.d.ts +2 -1
  264. package/dist/esm/router/dashboard/[contentType]/[edit]/screen.d.ts.map +1 -1
  265. package/dist/esm/router/dashboard/[contentType]/[edit]/screen.js +2 -2
  266. package/dist/esm/router/dashboard/[contentType]/[edit]/screen.js.map +1 -1
  267. package/dist/esm/router/dashboard/debugging/api-routes/ApiTest.d.ts.map +1 -1
  268. package/dist/esm/router/dashboard/debugging/api-routes/ApiTest.js +2 -2
  269. package/dist/esm/router/dashboard/debugging/api-routes/ApiTest.js.map +1 -1
  270. package/dist/esm/router/dashboard/debugging/api-routes/JsonViewer.d.ts +5 -0
  271. package/dist/esm/router/dashboard/debugging/api-routes/JsonViewer.d.ts.map +1 -0
  272. package/dist/esm/router/dashboard/debugging/api-routes/JsonViewer.js +14 -0
  273. package/dist/esm/router/dashboard/debugging/api-routes/JsonViewer.js.map +1 -0
  274. package/dist/esm/router/dashboard/debugging/api-routes/SchemaViewer.d.ts.map +1 -1
  275. package/dist/esm/router/dashboard/debugging/api-routes/SchemaViewer.js +42 -28
  276. package/dist/esm/router/dashboard/debugging/api-routes/SchemaViewer.js.map +1 -1
  277. package/dist/esm/router/dashboard/debugging/api-routes/test.d.ts.map +1 -1
  278. package/dist/esm/router/dashboard/debugging/api-routes/test.js +6 -5
  279. package/dist/esm/router/dashboard/debugging/api-routes/test.js.map +1 -1
  280. package/dist/esm/router/dashboard/seo/index.d.ts +2 -0
  281. package/dist/esm/router/dashboard/seo/index.d.ts.map +1 -0
  282. package/dist/esm/router/dashboard/seo/index.js +2 -0
  283. package/dist/esm/router/dashboard/seo/index.js.map +1 -0
  284. package/dist/esm/router/dashboard/seo/screen.d.ts +6 -0
  285. package/dist/esm/router/dashboard/seo/screen.d.ts.map +1 -0
  286. package/dist/esm/router/dashboard/seo/screen.js +212 -0
  287. package/dist/esm/router/dashboard/seo/screen.js.map +1 -0
  288. package/dist/esm/router/dashboard/seo/site-analysis.d.ts +40 -0
  289. package/dist/esm/router/dashboard/seo/site-analysis.d.ts.map +1 -0
  290. package/dist/esm/router/dashboard/seo/site-analysis.js +148 -0
  291. package/dist/esm/router/dashboard/seo/site-analysis.js.map +1 -0
  292. package/dist/esm/router/dashboard/settings/llms/index.d.ts +2 -0
  293. package/dist/esm/router/dashboard/settings/llms/index.d.ts.map +1 -0
  294. package/dist/esm/router/dashboard/settings/llms/index.js +2 -0
  295. package/dist/esm/router/dashboard/settings/llms/index.js.map +1 -0
  296. package/dist/esm/router/dashboard/settings/llms/screen.d.ts +2 -0
  297. package/dist/esm/router/dashboard/settings/llms/screen.d.ts.map +1 -0
  298. package/dist/esm/router/dashboard/settings/llms/screen.js +115 -0
  299. package/dist/esm/router/dashboard/settings/llms/screen.js.map +1 -0
  300. package/dist/esm/router/dashboard/settings/screen.d.ts.map +1 -1
  301. package/dist/esm/router/dashboard/settings/screen.js +8 -1
  302. package/dist/esm/router/dashboard/settings/screen.js.map +1 -1
  303. package/dist/esm/router/shared/route-definitions.d.ts +6 -2
  304. package/dist/esm/router/shared/route-definitions.d.ts.map +1 -1
  305. package/dist/esm/router/shared/route-definitions.js +3 -2
  306. package/dist/esm/router/shared/route-definitions.js.map +1 -1
  307. package/dist/esm/router/shared/route-list.d.ts +1 -1
  308. package/dist/esm/router/shared/route-list.d.ts.map +1 -1
  309. package/dist/esm/router/shared/route-list.js +17 -1
  310. package/dist/esm/router/shared/route-list.js.map +1 -1
  311. package/dist/esm/router/shared/route-renderer.d.ts.map +1 -1
  312. package/dist/esm/router/shared/route-renderer.js +2 -1
  313. package/dist/esm/router/shared/route-renderer.js.map +1 -1
  314. package/dist/esm/router/shared/types.d.ts +5 -0
  315. package/dist/esm/router/shared/types.d.ts.map +1 -1
  316. package/dist/styles.css +237 -6
  317. package/dist/tsconfig.build.tsbuildinfo +1 -1
  318. package/package.json +3 -3
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  'use client';
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.DynamicDataControl = exports.buildFilter = exports.readFilterState = exports.currentDocumentListSourceOptions = exports.sourceFieldOptions = exports.isDynamicFieldEnabled = exports.isDynamicFallbackRequired = void 0;
4
+ exports.DynamicDataControl = exports.listItemTargetFields = exports.buildFilter = exports.readFilterState = exports.currentDocumentListSourceOptions = exports.sourceFieldOptions = exports.isDynamicFieldEnabled = exports.targetMappingFields = exports.isMappableDynamicListField = exports.isDynamicFallbackRequired = void 0;
5
5
  const jsx_runtime_1 = require("react/jsx-runtime");
6
6
  const i18n_1 = require("../../../../../i18n/index.js");
7
7
  const client_1 = require("@rakun-kit/core/client");
@@ -20,61 +20,59 @@ const LanguageClientProvider_1 = require("../../../../../lib/providers/language/
20
20
  const isDynamicFallbackRequired = (field, binding) => field.isRequired && !binding;
21
21
  exports.isDynamicFallbackRequired = isDynamicFallbackRequired;
22
22
  const CURRENT_DOCUMENT_ID = '__rakun_current_document__';
23
- const cloneDynamicBindings = (bindings) => (bindings ? structuredClone(bindings) : undefined);
23
+ const cloneDynamicBindings = (bindings) => bindings ? structuredClone(bindings) : undefined;
24
24
  const cleanDynamicBindings = (bindings) => {
25
25
  if (!bindings)
26
26
  return undefined;
27
- const fields = bindings.fields && Object.keys(bindings.fields).length > 0
28
- ? bindings.fields
29
- : undefined;
30
- const lists = bindings.lists && Object.keys(bindings.lists).length > 0
31
- ? bindings.lists
32
- : undefined;
27
+ const fields = bindings.fields && Object.keys(bindings.fields).length > 0 ? bindings.fields : undefined;
28
+ const lists = bindings.lists && Object.keys(bindings.lists).length > 0 ? bindings.lists : undefined;
33
29
  return fields || lists ? { fields, lists } : undefined;
34
30
  };
35
31
  const isRecord = (value) => !!value && typeof value === 'object' && !Array.isArray(value);
36
- const isListField = (field) => field.config.ui === 'List' || field.config.ui === 'Iterator';
32
+ const isListField = (field) => field.config.capabilities.dynamic?.collection === 'heterogeneous';
33
+ const isMappableDynamicListField = (field) => {
34
+ if (isListField(field))
35
+ return true;
36
+ if (field.config.capabilities.dynamic?.collection !== 'homogeneous' || !('field' in field))
37
+ return false;
38
+ const itemField = field.field;
39
+ return !!(itemField.config.capabilities.dynamic?.relation ||
40
+ itemField.config.capabilities.dynamic?.mapProperties);
41
+ };
42
+ exports.isMappableDynamicListField = isMappableDynamicListField;
37
43
  const isRelatedCollectionSource = (source) => !!source && 'kind' in source && source.kind === 'relatedCollection';
38
44
  const isNestedListSource = (source) => !!source && 'kind' in source && source.kind === 'list';
39
- const asListField = (field) => field.config.ui === 'List' || field.config.ui === 'Iterator'
40
- ? field
41
- : undefined;
45
+ const asMappableListField = (field) => (0, exports.isMappableDynamicListField)(field) ? field : undefined;
42
46
  const isDynamicVisibleField = (field) => (field.visibility ?? 'all') === 'all' && field.isDynamic !== false;
43
47
  const isSelectableDynamicField = (name, field) => name !== client_1.ITERATOR_FIELD_NAME && isDynamicVisibleField(field);
48
+ const propertyTargetField = (field, valueKind) => ({
49
+ ...field,
50
+ config: {
51
+ ...field.config,
52
+ capabilities: { valueKind },
53
+ },
54
+ });
55
+ const propertyMappingFields = (field) => Object.entries(field.config.capabilities.dynamic?.properties ?? {}).map(([property, valueKind]) => [property, propertyTargetField(field, valueKind)]);
56
+ const targetMappingFields = (contentType) => contentType
57
+ ? Object.entries(contentType.fields).flatMap(([name, field]) => {
58
+ if (!isSelectableDynamicField(name, field))
59
+ return [];
60
+ const properties = field.config.capabilities.dynamic?.mapProperties
61
+ ? propertyMappingFields(field)
62
+ : [];
63
+ if (properties.length > 0) {
64
+ return properties.map(([property, propertyField]) => [`${name}.${property}`, propertyField]);
65
+ }
66
+ return [[name, field]];
67
+ })
68
+ : [];
69
+ exports.targetMappingFields = targetMappingFields;
44
70
  const isDynamicFieldEnabled = (contentType, field) => {
45
- return (contentType.dynamicData !== false &&
46
- isDynamicVisibleField(field));
71
+ return contentType.dynamicData !== false && isDynamicVisibleField(field);
47
72
  };
48
73
  exports.isDynamicFieldEnabled = isDynamicFieldEnabled;
49
74
  const getFieldKind = (field) => {
50
- if (field.config.type === 'String') {
51
- return field.config.ui === 'RichText' ? 'richText' : 'string';
52
- }
53
- if (field.config.type === 'Link')
54
- return 'string';
55
- if (field.config.type === 'Number')
56
- return 'number';
57
- if (field.config.type === 'Boolean')
58
- return 'boolean';
59
- if (field.config.type === 'Date') {
60
- return field.config.ui === 'Time' ? 'string' : 'date';
61
- }
62
- if (field.config.type === 'Select') {
63
- return field.isMultiple ? 'array' : 'string';
64
- }
65
- if (field.config.type === 'ContentReference') {
66
- return field.isMultiple ? 'array' : 'string';
67
- }
68
- if (field.config.type === 'File') {
69
- return field.isMultiple ? 'array' : 'object';
70
- }
71
- if (field.config.type === 'Relation')
72
- return 'object';
73
- if (field.config.ui === 'SimpleList')
74
- return 'array';
75
- if (isListField(field))
76
- return 'array';
77
- return 'unknown';
75
+ return field.config.capabilities.valueKind;
78
76
  };
79
77
  const isCompatibleSourceKind = (sourceKind, targetField) => {
80
78
  if (!targetField)
@@ -102,35 +100,12 @@ const areFieldKindsCompatible = (sourceField, targetField) => {
102
100
  };
103
101
  const fieldLabel = (path) => path.startsWith('_seo.') ? `seo.${path.slice('_seo.'.length)}` : path;
104
102
  const isSeoPath = (path) => path.split('.').some((segment) => segment === '_seo' || segment === 'seo');
105
- const fileFieldOptions = (path, targetField) => {
106
- const options = [
107
- { label: fieldLabel(`${path}.url`), value: `${path}.url`, kind: 'string' },
108
- {
109
- label: fieldLabel(`${path}.previewUrl`),
110
- value: `${path}.previewUrl`,
111
- kind: 'string',
112
- },
113
- { label: fieldLabel(`${path}.name`), value: `${path}.name`, kind: 'string' },
114
- {
115
- label: fieldLabel(`${path}.title`),
116
- value: `${path}.title`,
117
- kind: 'string',
118
- },
119
- { label: fieldLabel(`${path}.alt`), value: `${path}.alt`, kind: 'string' },
120
- { label: fieldLabel(`${path}.mime`), value: `${path}.mime`, kind: 'string' },
121
- {
122
- label: fieldLabel(`${path}.srcSet`),
123
- value: `${path}.srcSet`,
124
- kind: 'string',
125
- },
126
- { label: fieldLabel(`${path}.width`), value: `${path}.width`, kind: 'number' },
127
- {
128
- label: fieldLabel(`${path}.height`),
129
- value: `${path}.height`,
130
- kind: 'number',
131
- },
132
- { label: fieldLabel(`${path}.size`), value: `${path}.size`, kind: 'number' },
133
- ];
103
+ const propertyFieldOptions = (path, field, targetField) => {
104
+ const options = Object.entries(field.config.capabilities.dynamic?.properties ?? {}).map(([property, kind]) => ({
105
+ label: fieldLabel(`${path}.${property}`),
106
+ value: `${path}.${property}`,
107
+ kind,
108
+ }));
134
109
  return options.filter((option) => isCompatibleSourceKind(option.kind, targetField));
135
110
  };
136
111
  const nestedSourceFieldOptions = ({ contentType, prefix = '', targetField, depth = 0, }) => Object.entries(contentType.fields).flatMap(([name, field]) => {
@@ -140,7 +115,7 @@ const nestedSourceFieldOptions = ({ contentType, prefix = '', targetField, depth
140
115
  const kind = getFieldKind(field);
141
116
  if (isSeoPath(path))
142
117
  return [];
143
- if (field.config.type === 'Relation' && depth < 3) {
118
+ if (field.config.capabilities.dynamic?.relation && depth < 3) {
144
119
  const relationContentType = field.contentType;
145
120
  const idOption = isCompatibleSourceKind('string', targetField)
146
121
  ? [
@@ -161,7 +136,8 @@ const nestedSourceFieldOptions = ({ contentType, prefix = '', targetField, depth
161
136
  }),
162
137
  ];
163
138
  }
164
- if (field.config.type === 'File') {
139
+ const properties = field.config.capabilities.dynamic?.properties;
140
+ if (properties) {
165
141
  const fieldOption = areFieldKindsCompatible(field, targetField)
166
142
  ? [
167
143
  {
@@ -171,25 +147,9 @@ const nestedSourceFieldOptions = ({ contentType, prefix = '', targetField, depth
171
147
  },
172
148
  ]
173
149
  : [];
174
- if (field.isMultiple)
175
- return fieldOption;
176
- return [...fieldOption, ...fileFieldOptions(path, targetField)];
177
- }
178
- if (field.config.type === 'Link') {
179
- const fieldOption = targetField?.config.type === 'Link' &&
180
- areFieldKindsCompatible(field, targetField)
181
- ? [{ label: fieldLabel(path), value: path, kind }]
182
- : [];
183
- const propertyOptions = ['href', 'title'].flatMap((property) => isCompatibleSourceKind('string', targetField)
184
- ? [
185
- {
186
- label: fieldLabel(`${path}.${property}`),
187
- value: `${path}.${property}`,
188
- kind: 'string',
189
- },
190
- ]
191
- : []);
192
- return [...fieldOption, ...propertyOptions];
150
+ return kind === 'object'
151
+ ? [...fieldOption, ...propertyFieldOptions(path, field, targetField)]
152
+ : fieldOption;
193
153
  }
194
154
  if (!areFieldKindsCompatible(field, targetField))
195
155
  return [];
@@ -207,18 +167,15 @@ const sourceFieldOptions = (contentType, targetField) => {
207
167
  const fields = nestedSourceFieldOptions({ contentType, targetField });
208
168
  const includeHref = contentType.routes?.some((route) => route.hasPage) &&
209
169
  isCompatibleSourceKind('string', targetField);
210
- return includeHref
211
- ? [{ label: 'href', value: '$href', kind: 'string' }, ...fields]
212
- : fields;
170
+ return includeHref ? [{ label: 'href', value: '$href', kind: 'string' }, ...fields] : fields;
213
171
  };
214
172
  exports.sourceFieldOptions = sourceFieldOptions;
215
173
  const currentDocumentListSourceValue = (path, itemName) => `current-document:${path}:${itemName ?? ''}`;
216
174
  const currentDocumentListSourceOptions = (contentType) => Object.entries(contentType.fields).flatMap(([name, field]) => {
217
175
  if (!isSelectableDynamicField(name, field) || field.isTranslatable)
218
176
  return [];
219
- if (field.config.ui === 'List' || field.config.ui === 'Iterator') {
220
- const relationEntries = field.fields.filter((entry) => entry.name !== client_1.ITERATOR_FIELD_NAME &&
221
- entry.field.config.type === 'Relation');
177
+ if (field.config.capabilities.dynamic?.collection === 'heterogeneous' && 'fields' in field) {
178
+ const relationEntries = field.fields.filter((entry) => entry.name !== client_1.ITERATOR_FIELD_NAME && entry.field.config.capabilities.dynamic?.relation);
222
179
  return relationEntries.map((entry) => ({
223
180
  label: relationEntries.length === 1
224
181
  ? `Current document · ${name}`
@@ -229,9 +186,9 @@ const currentDocumentListSourceOptions = (contentType) => Object.entries(content
229
186
  itemName: entry.name,
230
187
  }));
231
188
  }
232
- if (field.config.ui === 'SimpleList') {
189
+ if (field.config.capabilities.dynamic?.collection === 'homogeneous' && 'field' in field) {
233
190
  const itemField = field.field;
234
- if (itemField.config.type !== 'Relation')
191
+ if (!itemField.config.capabilities.dynamic?.relation)
235
192
  return [];
236
193
  return [
237
194
  {
@@ -245,9 +202,7 @@ const currentDocumentListSourceOptions = (contentType) => Object.entries(content
245
202
  return [];
246
203
  });
247
204
  exports.currentDocumentListSourceOptions = currentDocumentListSourceOptions;
248
- const createSource = (contentType, value, id) => value === '$href'
249
- ? { contentType, id, virtual: 'href' }
250
- : { contentType, id, path: value };
205
+ const createSource = (contentType, value, id) => value === '$href' ? { contentType, id, virtual: 'href' } : { contentType, id, path: value };
251
206
  const sourceValue = (source) => source?.virtual === 'href' ? '$href' : source?.path || '';
252
207
  const sourceLabel = (source) => source?.virtual === 'href' ? 'href' : fieldLabel(source?.path || '');
253
208
  const mappingSourceSummary = (source, currentSourceName) => {
@@ -292,15 +247,13 @@ const operatorByMongoOperator = {
292
247
  $lte: 'lessThanOrEqual',
293
248
  };
294
249
  const readFilterOperand = (value) => {
295
- if (isRecord(value) &&
296
- typeof value[client_1.DYNAMIC_QUERY_CURRENT_VALUE_KEY] === 'string') {
250
+ if (isRecord(value) && typeof value[client_1.DYNAMIC_QUERY_CURRENT_VALUE_KEY] === 'string') {
297
251
  return {
298
252
  value: value[client_1.DYNAMIC_QUERY_CURRENT_VALUE_KEY],
299
253
  valueSource: 'current',
300
254
  };
301
255
  }
302
- if (isRecord(value) &&
303
- typeof value[client_1.DYNAMIC_QUERY_DOCUMENT_VALUE_KEY] === 'string') {
256
+ if (isRecord(value) && typeof value[client_1.DYNAMIC_QUERY_DOCUMENT_VALUE_KEY] === 'string') {
304
257
  return {
305
258
  value: value[client_1.DYNAMIC_QUERY_DOCUMENT_VALUE_KEY],
306
259
  valueSource: 'document',
@@ -316,8 +269,7 @@ const filterConditionFromEntry = (field, value) => {
316
269
  if (value === false)
317
270
  return { field, operator: 'false', value: '' };
318
271
  const directOperand = readFilterOperand(value);
319
- if (directOperand.valueSource === 'current' ||
320
- directOperand.valueSource === 'document') {
272
+ if (directOperand.valueSource === 'current' || directOperand.valueSource === 'document') {
321
273
  return { field, operator: 'equals', ...directOperand };
322
274
  }
323
275
  if (isRecord(value)) {
@@ -413,9 +365,7 @@ const buildFilterCondition = (condition, fieldOptions) => {
413
365
  lessThanOrEqual: '$lte',
414
366
  };
415
367
  const operator = mongoOperator[condition.operator];
416
- return operator
417
- ? { [condition.field]: { [operator]: value } }
418
- : { [condition.field]: value };
368
+ return operator ? { [condition.field]: { [operator]: value } } : { [condition.field]: value };
419
369
  };
420
370
  const buildFilter = (state, fieldOptions = []) => {
421
371
  const conditions = state.conditions.flatMap((condition) => {
@@ -486,8 +436,8 @@ const bindingSummary = ({ list, fieldBinding, listBinding, documentContentTypeNa
486
436
  return '';
487
437
  return `${sourceContentTypeLabel(fieldBinding, documentContentTypeName)} -> ${sourceLabel(fieldBinding)}`;
488
438
  };
489
- const PanelSection = ({ title, children, }) => ((0, jsx_runtime_1.jsxs)("div", { className: 'grid gap-3 rounded-md border border-border bg-muted/20 p-3', children: [(0, jsx_runtime_1.jsx)("div", { className: 'text-xs font-semibold uppercase text-muted-foreground', children: title }), children] }));
490
- const ControlLabel = ({ children, help, }) => ((0, jsx_runtime_1.jsxs)("div", { className: 'flex items-center gap-1.5', children: [(0, jsx_runtime_1.jsx)(label_1.Label, { children: children }), (0, jsx_runtime_1.jsxs)(tooltip_1.Tooltip, { children: [(0, jsx_runtime_1.jsx)(tooltip_1.TooltipTrigger, { asChild: true, children: (0, jsx_runtime_1.jsx)("button", { type: 'button', className: 'rounded-sm text-muted-foreground outline-none hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring', "aria-label": help, children: (0, jsx_runtime_1.jsx)(lucide_react_1.HelpCircle, { className: 'h-3.5 w-3.5' }) }) }), (0, jsx_runtime_1.jsx)(tooltip_1.TooltipContent, { side: 'top', sideOffset: 6, className: 'max-w-xs', children: help })] })] }));
439
+ const PanelSection = ({ title, children }) => ((0, jsx_runtime_1.jsxs)("div", { className: "grid gap-3 rounded-md border border-border bg-muted/20 p-3", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs font-semibold uppercase text-muted-foreground", children: title }), children] }));
440
+ const ControlLabel = ({ children, help }) => ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1.5", children: [(0, jsx_runtime_1.jsx)(label_1.Label, { children: children }), (0, jsx_runtime_1.jsxs)(tooltip_1.Tooltip, { children: [(0, jsx_runtime_1.jsx)(tooltip_1.TooltipTrigger, { asChild: true, children: (0, jsx_runtime_1.jsx)("button", { type: "button", className: "rounded-sm text-muted-foreground outline-none hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring", "aria-label": help, children: (0, jsx_runtime_1.jsx)(lucide_react_1.HelpCircle, { className: "h-3.5 w-3.5" }) }) }), (0, jsx_runtime_1.jsx)(tooltip_1.TooltipContent, { side: "top", sideOffset: 6, className: "max-w-xs", children: help })] })] }));
491
441
  const FieldBindingEditor = ({ contentTypes, documentContentType, currentDocumentSourceEnabled, targetField, binding, onChange, }) => {
492
442
  const t = (0, i18n_1.useTranslations)();
493
443
  const { language } = (0, LanguageClientProvider_1.useLanguage)();
@@ -513,9 +463,7 @@ const FieldBindingEditor = ({ contentTypes, documentContentType, currentDocument
513
463
  },
514
464
  },
515
465
  },
516
- enabled: !!sourceType &&
517
- !usesCurrentDocumentSource &&
518
- selectedContentType?.dynamicDataSource === true,
466
+ enabled: !!sourceType && !usesCurrentDocumentSource && selectedContentType?.dynamicDataSource === true,
519
467
  });
520
468
  const items = (sourceItemsQuery.data?.items ?? []);
521
469
  const hasCurrentDocumentItem = currentDocumentSourceEnabled && sourceType === documentContentType.name;
@@ -531,48 +479,73 @@ const FieldBindingEditor = ({ contentTypes, documentContentType, currentDocument
531
479
  }
532
480
  onChange(createSource(nextType, nextPath, usesCurrentDocument ? undefined : nextId));
533
481
  };
534
- return ((0, jsx_runtime_1.jsx)(PanelSection, { title: 'Source value', children: (0, jsx_runtime_1.jsxs)("div", { className: 'grid gap-3 md:grid-cols-[1fr_1.4fr_1fr]', children: [(0, jsx_runtime_1.jsxs)(label_1.Label, { className: 'grid gap-1.5', children: [t('dynamicData.source'), (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: contentTypes.length === 0, value: sourceType, onValueChange: (value) => {
535
- const nextId = currentDocumentSourceEnabled &&
536
- value === documentContentType.name
482
+ return ((0, jsx_runtime_1.jsx)(PanelSection, { title: "Source value", children: (0, jsx_runtime_1.jsxs)("div", { className: "grid gap-3 md:grid-cols-[1fr_1.4fr_1fr]", children: [(0, jsx_runtime_1.jsxs)(label_1.Label, { className: "grid gap-1.5", children: [t('dynamicData.source'), (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: contentTypes.length === 0, value: sourceType, onValueChange: (value) => {
483
+ const nextId = currentDocumentSourceEnabled && value === documentContentType.name
537
484
  ? CURRENT_DOCUMENT_ID
538
485
  : '';
539
486
  setSourceType(value);
540
487
  setSourceId(nextId);
541
488
  setFieldPath('');
542
489
  onChange(undefined);
543
- }, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'w-full', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: contentTypes.length > 0 ? 'Content type' : 'No content types' }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: (0, jsx_runtime_1.jsx)(select_1.SelectGroup, { children: contentTypes.map((ct) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: ct.name, children: currentDocumentSourceEnabled &&
544
- ct.name === documentContentType.name
490
+ }, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: "w-full", children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: contentTypes.length > 0 ? 'Content type' : 'No content types' }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: (0, jsx_runtime_1.jsx)(select_1.SelectGroup, { children: contentTypes.map((ct) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: ct.name, children: currentDocumentSourceEnabled && ct.name === documentContentType.name
545
491
  ? `${ct.name} (current document)`
546
- : ct.name }, ct.name))) }) })] })] }), (0, jsx_runtime_1.jsxs)(label_1.Label, { className: 'grid gap-1.5', children: [t('dynamicData.item'), (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: !sourceType || !hasItemOptions, value: sourceId, onValueChange: (value) => {
492
+ : ct.name }, ct.name))) }) })] })] }), (0, jsx_runtime_1.jsxs)(label_1.Label, { className: "grid gap-1.5", children: [t('dynamicData.item'), (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: !sourceType || !hasItemOptions, value: sourceId, onValueChange: (value) => {
547
493
  setSourceId(value);
548
494
  emit(sourceType, value, fieldPath);
549
- }, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'w-full', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: hasItemOptions ? 'Item' : 'No items available' }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: (0, jsx_runtime_1.jsxs)(select_1.SelectGroup, { children: [hasCurrentDocumentItem ? ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: CURRENT_DOCUMENT_ID, children: t('dynamicData.currentDocument') })) : null, items.map((item) => {
495
+ }, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: "w-full", children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: hasItemOptions ? 'Item' : 'No items available' }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: (0, jsx_runtime_1.jsxs)(select_1.SelectGroup, { children: [hasCurrentDocumentItem ? ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: CURRENT_DOCUMENT_ID, children: t('dynamicData.currentDocument') })) : null, items.map((item) => {
550
496
  const label = selectedContentType
551
497
  ? (0, client_1.getListField)(item, selectedContentType.listFields ?? [])
552
498
  : item._id;
553
499
  return ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: item._id, children: (0, client_1.isTranslatableObject)(label)
554
500
  ? label[language.code]
555
501
  : String(label || item._id) }, item._id));
556
- })] }) })] })] }), (0, jsx_runtime_1.jsxs)(label_1.Label, { className: 'grid gap-1.5', children: [t('dynamicData.field'), (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: !sourceType || !sourceId || fieldOptions.length === 0, value: fieldPath, onValueChange: (value) => {
502
+ })] }) })] })] }), (0, jsx_runtime_1.jsxs)(label_1.Label, { className: "grid gap-1.5", children: [t('dynamicData.field'), (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: !sourceType || !sourceId || fieldOptions.length === 0, value: fieldPath, onValueChange: (value) => {
557
503
  setFieldPath(value);
558
504
  emit(sourceType, sourceId, value);
559
- }, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'w-full', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: fieldOptions.length > 0 ? 'Field' : 'No compatible fields' }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: (0, jsx_runtime_1.jsx)(select_1.SelectGroup, { children: fieldOptions.map((field) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: field.value, children: field.label }, field.value))) }) })] })] })] }) }));
505
+ }, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: "w-full", children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: fieldOptions.length > 0 ? 'Field' : 'No compatible fields' }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: (0, jsx_runtime_1.jsx)(select_1.SelectGroup, { children: fieldOptions.map((field) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: field.value, children: field.label }, field.value))) }) })] })] })] }) }));
560
506
  };
561
507
  const getListTargetContentType = (field, itemName) => {
562
- const entry = field.fields.find((item) => item.name === itemName);
563
- if (!entry || entry.field.config.type !== 'Relation')
508
+ if (field.config.capabilities.dynamic?.collection === 'homogeneous') {
509
+ const itemField = field.field;
510
+ return itemField.config.capabilities.dynamic?.relation
511
+ ? itemField.contentType
512
+ : undefined;
513
+ }
514
+ const listField = field;
515
+ const entry = listField.fields.find((item) => item.name === itemName);
516
+ if (!entry || !entry.field.config.capabilities.dynamic?.relation)
564
517
  return undefined;
565
518
  return entry.field.contentType;
566
519
  };
520
+ const getListItemOptions = (field) => {
521
+ if (field.config.capabilities.dynamic?.collection !== 'homogeneous') {
522
+ return field.fields.filter((item) => item.name !== client_1.ITERATOR_FIELD_NAME);
523
+ }
524
+ const itemField = field.field;
525
+ const name = itemField.config.capabilities.dynamic?.relation
526
+ ? itemField.contentType.name
527
+ : (itemField.config.editor ?? itemField.config.type);
528
+ return [{ name, field: itemField }];
529
+ };
530
+ const listItemTargetFields = (field, itemName) => {
531
+ if (field.config.capabilities.dynamic?.collection === 'homogeneous') {
532
+ const itemField = field.field;
533
+ if (itemField.config.capabilities.dynamic?.mapProperties) {
534
+ return propertyMappingFields(itemField);
535
+ }
536
+ }
537
+ return (0, exports.targetMappingFields)(getListTargetContentType(field, itemName));
538
+ };
539
+ exports.listItemTargetFields = listItemTargetFields;
567
540
  const getRelationContentType = (field) => {
568
541
  if (field.isTranslatable)
569
542
  return undefined;
570
- if (field.config.type === 'Relation') {
543
+ if (field.config.capabilities.dynamic?.relation) {
571
544
  return field.contentType;
572
545
  }
573
- if (field.config.ui === 'SimpleList') {
546
+ if (field.config.capabilities.dynamic?.collection === 'homogeneous' && 'field' in field) {
574
547
  const itemField = field.field;
575
- if (itemField.config.type === 'Relation') {
548
+ if (itemField.config.capabilities.dynamic?.relation) {
576
549
  return itemField.contentType;
577
550
  }
578
551
  }
@@ -593,13 +566,7 @@ const getSortFieldOptions = (contentType) => Object.entries(contentType.fields).
593
566
  return [];
594
567
  }
595
568
  const kind = getFieldKind(field);
596
- const isSingleSelect = field.config.type === 'Select' &&
597
- !field.isMultiple;
598
- const isSortable = (field.config.type === 'String' && field.config.ui !== 'RichText') ||
599
- field.config.type === 'Number' ||
600
- field.config.type === 'Boolean' ||
601
- field.config.type === 'Date' ||
602
- isSingleSelect;
569
+ const isSortable = ['string', 'number', 'boolean', 'date'].includes(kind);
603
570
  return isSortable ? [{ label: fieldLabel(name), value: name, kind }] : [];
604
571
  });
605
572
  const filterOperatorOptions = {
@@ -640,19 +607,11 @@ const getFilterOperatorOptions = (kind) => {
640
607
  'notExists',
641
608
  ]
642
609
  : kind === 'string' || kind === 'richText'
643
- ? [
644
- 'equals',
645
- 'notEquals',
646
- 'contains',
647
- 'in',
648
- 'notIn',
649
- 'exists',
650
- 'notExists',
651
- ]
610
+ ? ['equals', 'notEquals', 'contains', 'in', 'notIn', 'exists', 'notExists']
652
611
  : ['equals', 'notEquals', 'exists', 'notExists'];
653
612
  return operators.map((operator) => filterOperatorOptions[operator]);
654
613
  };
655
- const defaultFilterOperator = (kind) => (kind === 'boolean' ? 'true' : 'equals');
614
+ const defaultFilterOperator = (kind) => kind === 'boolean' ? 'true' : 'equals';
656
615
  const createRelatedCollectionSource = ({ contentType, currentSource, targetField, }) => {
657
616
  const relation = getRelatedRelationOptions(contentType, currentSource)[0];
658
617
  const path = getRelatedPathOptions(contentType, targetField)[0]?.value;
@@ -668,12 +627,10 @@ const createRelatedCollectionSource = ({ contentType, currentSource, targetField
668
627
  };
669
628
  const MappingSourceEditor = ({ contentTypes, rootDocumentContentType, currentSource, targetField, source, onChange, }) => {
670
629
  const t = (0, i18n_1.useTranslations)();
671
- const nestedListTarget = asListField(targetField);
630
+ const nestedListTarget = asMappableListField(targetField);
672
631
  const nestedSource = isNestedListSource(source) ? source : undefined;
673
632
  const relatedSource = isRelatedCollectionSource(source) ? source : undefined;
674
- const directSource = source && !isRelatedCollectionSource(source) && !isNestedListSource(source)
675
- ? source
676
- : undefined;
633
+ const directSource = source && !isRelatedCollectionSource(source) && !isNestedListSource(source) ? source : undefined;
677
634
  const directFieldOptions = (0, exports.sourceFieldOptions)(currentSource, targetField);
678
635
  const relatedContentTypes = contentTypes.filter((contentType) => getRelatedRelationOptions(contentType, currentSource).length > 0 &&
679
636
  getRelatedPathOptions(contentType, targetField).length > 0);
@@ -693,7 +650,9 @@ const MappingSourceEditor = ({ contentTypes, rootDocumentContentType, currentSou
693
650
  const sortField = sortEntry?.[0] ?? '';
694
651
  const sortDirection = sortEntry?.[1] ?? 'desc';
695
652
  const createNestedSource = () => {
696
- const nestedItemName = nestedListTarget?.fields.find((item) => item.name !== client_1.ITERATOR_FIELD_NAME)?.name;
653
+ const nestedItemName = nestedListTarget
654
+ ? getListItemOptions(nestedListTarget)[0]?.name
655
+ : undefined;
697
656
  if (!nestedItemName)
698
657
  return undefined;
699
658
  return {
@@ -705,13 +664,13 @@ const MappingSourceEditor = ({ contentTypes, rootDocumentContentType, currentSou
705
664
  };
706
665
  };
707
666
  if (nestedSource && nestedListTarget) {
708
- return ((0, jsx_runtime_1.jsxs)("div", { className: 'grid gap-3', children: [(0, jsx_runtime_1.jsxs)("div", { className: 'grid max-w-sm content-start gap-1.5', children: [(0, jsx_runtime_1.jsx)(ControlLabel, { help: t('dynamicData.nestedListHelp'), children: t('dynamicData.mappingMode') }), (0, jsx_runtime_1.jsxs)(select_1.Select, { value: 'list', onValueChange: (value) => {
667
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "grid gap-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "grid max-w-sm content-start gap-1.5", children: [(0, jsx_runtime_1.jsx)(ControlLabel, { help: t('dynamicData.nestedListHelp'), children: t('dynamicData.mappingMode') }), (0, jsx_runtime_1.jsxs)(select_1.Select, { value: "list", onValueChange: (value) => {
709
668
  if (value === 'field')
710
669
  onChange(undefined);
711
- }, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'w-full', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, {}) }), (0, jsx_runtime_1.jsxs)(select_1.SelectContent, { children: [(0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: 'field', children: t('dynamicData.directField') }), (0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: 'list', children: t('dynamicData.nestedList') })] })] })] }), (0, jsx_runtime_1.jsx)(ListBindingEditor, { contentTypes: contentTypes, documentContentType: currentSource, rootDocumentContentType: rootDocumentContentType, currentItemContentType: currentSource, currentDocumentSourceEnabled: true, field: nestedListTarget, binding: nestedSource, onChange: (binding) => onChange(binding ? { ...binding, kind: 'list' } : undefined) })] }));
670
+ }, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: "w-full", children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, {}) }), (0, jsx_runtime_1.jsxs)(select_1.SelectContent, { children: [(0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: "field", children: t('dynamicData.directField') }), (0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: "list", children: t('dynamicData.nestedList') })] })] })] }), (0, jsx_runtime_1.jsx)(ListBindingEditor, { contentTypes: contentTypes, documentContentType: currentSource, rootDocumentContentType: rootDocumentContentType, currentItemContentType: currentSource, currentDocumentSourceEnabled: true, field: nestedListTarget, binding: nestedSource, onChange: (binding) => onChange(binding ? { ...binding, kind: 'list' } : undefined) })] }));
712
671
  }
713
672
  if (!relatedSource) {
714
- return ((0, jsx_runtime_1.jsxs)("div", { className: 'grid gap-3 md:grid-cols-[0.7fr_1.3fr]', children: [(0, jsx_runtime_1.jsxs)("div", { className: 'grid content-start gap-1.5', children: [(0, jsx_runtime_1.jsx)(ControlLabel, { help: 'Choose a direct field or query a related collection.', children: t('dynamicData.mappingMode') }), (0, jsx_runtime_1.jsxs)(select_1.Select, { value: 'field', onValueChange: (value) => {
673
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "grid gap-3 md:grid-cols-[0.7fr_1.3fr]", children: [(0, jsx_runtime_1.jsxs)("div", { className: "grid content-start gap-1.5", children: [(0, jsx_runtime_1.jsx)(ControlLabel, { help: "Choose a direct field or query a related collection.", children: t('dynamicData.mappingMode') }), (0, jsx_runtime_1.jsxs)(select_1.Select, { value: "field", onValueChange: (value) => {
715
674
  if (value === 'list') {
716
675
  onChange(createNestedSource());
717
676
  return;
@@ -726,11 +685,9 @@ const MappingSourceEditor = ({ contentTypes, rootDocumentContentType, currentSou
726
685
  }))
727
686
  .find(Boolean);
728
687
  onChange(next);
729
- }, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'w-full', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, {}) }), (0, jsx_runtime_1.jsxs)(select_1.SelectContent, { children: [(0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: 'field', children: t('dynamicData.directField') }), relatedContentTypes.length > 0 ? ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: 'relatedCollection', children: t('dynamicData.relatedCollection') })) : null, nestedListTarget ? ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: 'list', children: t('dynamicData.nestedList') })) : null] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: 'grid content-start gap-1.5', children: [(0, jsx_runtime_1.jsxs)(ControlLabel, { help: 'Its value will be assigned to this mapped property.', children: [t('dynamicData.fieldOn'), " ", currentSource.name] }), (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: directFieldOptions.length === 0, value: sourceValue(directSource), onValueChange: (value) => onChange(createSource(currentSource.name, value)), children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'w-full', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: directFieldOptions.length > 0
730
- ? 'Select a source field'
731
- : 'No compatible fields' }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: (0, jsx_runtime_1.jsx)(select_1.SelectGroup, { children: directFieldOptions.map((item) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: item.value, children: item.label }, item.value))) }) })] })] })] }));
688
+ }, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: "w-full", children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, {}) }), (0, jsx_runtime_1.jsxs)(select_1.SelectContent, { children: [(0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: "field", children: t('dynamicData.directField') }), relatedContentTypes.length > 0 ? ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: "relatedCollection", children: t('dynamicData.relatedCollection') })) : null, nestedListTarget ? ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: "list", children: t('dynamicData.nestedList') })) : null] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "grid content-start gap-1.5", children: [(0, jsx_runtime_1.jsxs)(ControlLabel, { help: "Its value will be assigned to this mapped property.", children: [t('dynamicData.fieldOn'), " ", currentSource.name] }), (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: directFieldOptions.length === 0, value: sourceValue(directSource), onValueChange: (value) => onChange(createSource(currentSource.name, value)), children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: "w-full", children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: directFieldOptions.length > 0 ? 'Select a source field' : 'No compatible fields' }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: (0, jsx_runtime_1.jsx)(select_1.SelectGroup, { children: directFieldOptions.map((item) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: item.value, children: item.label }, item.value))) }) })] })] })] }));
732
689
  }
733
- return ((0, jsx_runtime_1.jsxs)("div", { className: 'grid gap-3', children: [(0, jsx_runtime_1.jsxs)("div", { className: 'grid gap-3 sm:grid-cols-2 lg:grid-cols-4', children: [(0, jsx_runtime_1.jsxs)("div", { className: 'grid content-start gap-1.5', children: [(0, jsx_runtime_1.jsx)(ControlLabel, { help: 'Query records related to the current source item.', children: t('dynamicData.mappingMode') }), (0, jsx_runtime_1.jsxs)(select_1.Select, { value: 'relatedCollection', onValueChange: (value) => onChange(value === 'list' ? createNestedSource() : undefined), children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'w-full', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, {}) }), (0, jsx_runtime_1.jsxs)(select_1.SelectContent, { children: [(0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: 'field', children: t('dynamicData.directField') }), (0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: 'relatedCollection', children: t('dynamicData.relatedCollection') }), nestedListTarget ? ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: 'list', children: t('dynamicData.nestedList') })) : null] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: 'grid content-start gap-1.5', children: [(0, jsx_runtime_1.jsx)(ControlLabel, { help: 'Content type whose records will be searched.', children: t('dynamicData.collectionToQuery') }), (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: relatedContentTypes.length === 0, value: relatedSource.contentType, onValueChange: (value) => {
690
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "grid gap-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "grid gap-3 sm:grid-cols-2 lg:grid-cols-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "grid content-start gap-1.5", children: [(0, jsx_runtime_1.jsx)(ControlLabel, { help: "Query records related to the current source item.", children: t('dynamicData.mappingMode') }), (0, jsx_runtime_1.jsxs)(select_1.Select, { value: "relatedCollection", onValueChange: (value) => onChange(value === 'list' ? createNestedSource() : undefined), children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: "w-full", children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, {}) }), (0, jsx_runtime_1.jsxs)(select_1.SelectContent, { children: [(0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: "field", children: t('dynamicData.directField') }), (0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: "relatedCollection", children: t('dynamicData.relatedCollection') }), nestedListTarget ? ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: "list", children: t('dynamicData.nestedList') })) : null] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "grid content-start gap-1.5", children: [(0, jsx_runtime_1.jsx)(ControlLabel, { help: "Content type whose records will be searched.", children: t('dynamicData.collectionToQuery') }), (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: relatedContentTypes.length === 0, value: relatedSource.contentType, onValueChange: (value) => {
734
691
  const contentType = relatedContentTypes.find((item) => item.name === value);
735
692
  if (!contentType)
736
693
  return;
@@ -739,66 +696,49 @@ const MappingSourceEditor = ({ contentTypes, rootDocumentContentType, currentSou
739
696
  currentSource,
740
697
  targetField,
741
698
  }));
742
- }, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'w-full', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: relatedContentTypes.length > 0
699
+ }, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: "w-full", children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: relatedContentTypes.length > 0
743
700
  ? 'Select a content type'
744
- : 'No compatible collections' }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: relatedContentTypes.map((contentType) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: contentType.name, children: contentType.name }, contentType.name))) })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: 'grid content-start gap-1.5', children: [(0, jsx_runtime_1.jsxs)(ControlLabel, { help: `Field on ${relatedSource.contentType} that points to ${currentSource.name}.`, children: [t('dynamicData.relationTo'), " ", currentSource.name] }), (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: relationOptions.length === 0, value: relatedSource.relation, onValueChange: (relation) => onChange({ ...relatedSource, relation }), children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'w-full', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: relationOptions.length > 0
745
- ? 'Select a relation field'
746
- : 'No compatible relations' }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: relationOptions.map((relation) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: relation, children: relation }, relation))) })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: 'grid content-start gap-1.5', children: [(0, jsx_runtime_1.jsx)(ControlLabel, { help: 'Arrays from matching records are flattened into one result.', children: t('dynamicData.arrayFieldToCollect') }), (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: pathOptions.length === 0, value: relatedSource.path, onValueChange: (path) => onChange({ ...relatedSource, path }), children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'w-full', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: pathOptions.length > 0
747
- ? 'Select an array field'
748
- : 'No compatible array fields' }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: pathOptions.map((option) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: option.value, children: option.label }, option.value))) })] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: 'grid gap-3 sm:grid-cols-[0.7fr_1fr_0.7fr]', children: [(0, jsx_runtime_1.jsxs)("div", { className: 'grid content-start gap-1.5', children: [(0, jsx_runtime_1.jsx)(ControlLabel, { help: `Number of ${relatedSource.contentType} records queried per ${currentSource.name}. Minimum 1, maximum 100.`, children: t('dynamicData.maximumRelatedRecords') }), (0, jsx_runtime_1.jsx)(input_1.Input, { type: 'number', min: 1, max: 100, value: String(relatedSource.limit), onChange: (event) => onChange({
701
+ : 'No compatible collections' }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: relatedContentTypes.map((contentType) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: contentType.name, children: contentType.name }, contentType.name))) })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "grid content-start gap-1.5", children: [(0, jsx_runtime_1.jsxs)(ControlLabel, { help: `Field on ${relatedSource.contentType} that points to ${currentSource.name}.`, children: [t('dynamicData.relationTo'), " ", currentSource.name] }), (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: relationOptions.length === 0, value: relatedSource.relation, onValueChange: (relation) => onChange({ ...relatedSource, relation }), children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: "w-full", children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: relationOptions.length > 0 ? 'Select a relation field' : 'No compatible relations' }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: relationOptions.map((relation) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: relation, children: relation }, relation))) })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "grid content-start gap-1.5", children: [(0, jsx_runtime_1.jsx)(ControlLabel, { help: "Arrays from matching records are flattened into one result.", children: t('dynamicData.arrayFieldToCollect') }), (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: pathOptions.length === 0, value: relatedSource.path, onValueChange: (path) => onChange({ ...relatedSource, path }), children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: "w-full", children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: pathOptions.length > 0 ? 'Select an array field' : 'No compatible array fields' }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: pathOptions.map((option) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: option.value, children: option.label }, option.value))) })] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "grid gap-3 sm:grid-cols-[0.7fr_1fr_0.7fr]", children: [(0, jsx_runtime_1.jsxs)("div", { className: "grid content-start gap-1.5", children: [(0, jsx_runtime_1.jsx)(ControlLabel, { help: `Number of ${relatedSource.contentType} records queried per ${currentSource.name}. Minimum 1, maximum 100.`, children: t('dynamicData.maximumRelatedRecords') }), (0, jsx_runtime_1.jsx)(input_1.Input, { type: "number", min: 1, max: 100, value: String(relatedSource.limit), onChange: (event) => onChange({
749
702
  ...relatedSource,
750
703
  limit: Math.min(100, Math.max(1, Number(event.target.value || 10))),
751
- }) })] }), (0, jsx_runtime_1.jsxs)("div", { className: 'grid content-start gap-1.5', children: [(0, jsx_runtime_1.jsx)(ControlLabel, { help: 'Optional. Only direct scalar fields can be used.', children: t('dynamicData.sortRelatedRecordsBy') }), (0, jsx_runtime_1.jsxs)(select_1.Select, { value: sortField || '__none__', onValueChange: (value) => onChange({
704
+ }) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "grid content-start gap-1.5", children: [(0, jsx_runtime_1.jsx)(ControlLabel, { help: "Optional. Only direct scalar fields can be used.", children: t('dynamicData.sortRelatedRecordsBy') }), (0, jsx_runtime_1.jsxs)(select_1.Select, { value: sortField || '__none__', onValueChange: (value) => onChange({
752
705
  ...relatedSource,
753
- sort: value === '__none__'
754
- ? undefined
755
- : { [value]: sortDirection },
756
- }), children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'w-full', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: t('dynamicData.noSort') }) }), (0, jsx_runtime_1.jsxs)(select_1.SelectContent, { children: [(0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: '__none__', children: t('dynamicData.noSort') }), sortOptions.map((option) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: option.value, children: option.label }, option.value)))] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: 'grid content-start gap-1.5', children: [(0, jsx_runtime_1.jsx)(ControlLabel, { help: 'Applied before collecting and flattening the arrays.', children: t('dynamicData.sortDirection') }), (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: !sortField, value: sortDirection, onValueChange: (direction) => sortField
706
+ sort: value === '__none__' ? undefined : { [value]: sortDirection },
707
+ }), children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: "w-full", children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: t('dynamicData.noSort') }) }), (0, jsx_runtime_1.jsxs)(select_1.SelectContent, { children: [(0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: "__none__", children: t('dynamicData.noSort') }), sortOptions.map((option) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: option.value, children: option.label }, option.value)))] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "grid content-start gap-1.5", children: [(0, jsx_runtime_1.jsx)(ControlLabel, { help: "Applied before collecting and flattening the arrays.", children: t('dynamicData.sortDirection') }), (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: !sortField, value: sortDirection, onValueChange: (direction) => sortField
757
708
  ? onChange({
758
709
  ...relatedSource,
759
710
  sort: { [sortField]: direction },
760
711
  })
761
- : undefined, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'w-full', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, {}) }), (0, jsx_runtime_1.jsxs)(select_1.SelectContent, { children: [(0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: 'asc', children: t('dynamicData.ascending') }), (0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: 'desc', children: t('dynamicData.descending') })] })] })] })] })] }));
712
+ : undefined, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: "w-full", children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, {}) }), (0, jsx_runtime_1.jsxs)(select_1.SelectContent, { children: [(0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: "asc", children: t('dynamicData.ascending') }), (0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: "desc", children: t('dynamicData.descending') })] })] })] })] })] }));
762
713
  };
763
714
  const ListBindingEditor = ({ contentTypes, documentContentType, rootDocumentContentType, currentItemContentType, currentDocumentSourceEnabled, field, binding, onChange, }) => {
764
715
  const t = (0, i18n_1.useTranslations)();
765
- const itemOptions = field.fields.filter((item) => item.name !== client_1.ITERATOR_FIELD_NAME);
716
+ const itemOptions = getListItemOptions(field);
766
717
  const documentSourceOptions = currentDocumentSourceEnabled
767
718
  ? (0, exports.currentDocumentListSourceOptions)(documentContentType)
768
719
  : [];
769
720
  const initialDocumentSource = binding?.source
770
- ? documentSourceOptions.find((option) => option.path === binding.source?.path &&
771
- option.itemName === binding.source?.itemName)
721
+ ? documentSourceOptions.find((option) => option.path === binding.source?.path && option.itemName === binding.source?.itemName)
772
722
  : undefined;
773
723
  const [sourceType, setSourceType] = (0, react_1.useState)(initialDocumentSource?.value || binding?.contentType || '');
774
724
  const [itemName, setItemName] = (0, react_1.useState)(binding?.itemName || itemOptions[0]?.name || '');
775
725
  const [filterState, setFilterState] = (0, react_1.useState)((0, exports.readFilterState)(binding?.query?.filter));
776
726
  const [openMappingField, setOpenMappingField] = (0, react_1.useState)(null);
777
727
  const selectedDocumentSource = documentSourceOptions.find((option) => option.value === sourceType);
778
- const selectedSource = selectedDocumentSource?.contentType ??
779
- contentTypes.find((ct) => ct.name === sourceType);
780
- const targetContentType = getListTargetContentType(field, itemName);
781
- const targetFields = (0, react_1.useMemo)(() => targetContentType
782
- ? Object.entries(targetContentType.fields).filter(([targetFieldName, targetField]) => isSelectableDynamicField(targetFieldName, targetField))
783
- : [], [targetContentType]);
784
- const sortFieldOptions = selectedSource
785
- ? getSortFieldOptions(selectedSource)
786
- : [];
728
+ const selectedSource = selectedDocumentSource?.contentType ?? contentTypes.find((ct) => ct.name === sourceType);
729
+ const targetFields = (0, react_1.useMemo)(() => (0, exports.listItemTargetFields)(field, itemName), [field, itemName]);
730
+ const sortFieldOptions = selectedSource ? getSortFieldOptions(selectedSource) : [];
787
731
  const filterFieldOptions = selectedSource
788
732
  ? (0, exports.sourceFieldOptions)(selectedSource).filter((item) => item.value !== '$href')
789
733
  : [];
790
734
  const currentDocumentFieldOptions = [
791
735
  { label: '_id', value: '_id', kind: 'string' },
792
- ...(0, exports.sourceFieldOptions)(rootDocumentContentType).filter((item) => item.value !== '$href' &&
793
- item.kind !== 'object' &&
794
- item.kind !== 'array'),
736
+ ...(0, exports.sourceFieldOptions)(rootDocumentContentType).filter((item) => item.value !== '$href' && item.kind !== 'object' && item.kind !== 'array'),
795
737
  ];
796
738
  const currentItemFieldOptions = currentItemContentType
797
739
  ? [
798
740
  { label: '_id', value: '_id', kind: 'string' },
799
- ...(0, exports.sourceFieldOptions)(currentItemContentType).filter((item) => item.value !== '$href' &&
800
- item.kind !== 'object' &&
801
- item.kind !== 'array'),
741
+ ...(0, exports.sourceFieldOptions)(currentItemContentType).filter((item) => item.value !== '$href' && item.kind !== 'object' && item.kind !== 'array'),
802
742
  ]
803
743
  : [];
804
744
  const sortEntry = Object.entries(binding?.query?.options?.sort ?? {})[0];
@@ -818,9 +758,7 @@ const ListBindingEditor = ({ contentTypes, documentContentType, rootDocumentCont
818
758
  source,
819
759
  itemName,
820
760
  map: binding?.map ?? {},
821
- query: source
822
- ? undefined
823
- : (binding?.query ?? { options: { limit: 10 } }),
761
+ query: source ? undefined : (binding?.query ?? { options: { limit: 10 } }),
824
762
  ...patch,
825
763
  };
826
764
  if (!next.contentType || !next.itemName) {
@@ -843,7 +781,7 @@ const ListBindingEditor = ({ contentTypes, documentContentType, rootDocumentCont
843
781
  conditions[index] = nextCondition;
844
782
  updateFilter({ ...filterState, conditions });
845
783
  };
846
- return ((0, jsx_runtime_1.jsxs)("div", { className: 'grid gap-3', children: [(0, jsx_runtime_1.jsx)(PanelSection, { title: 'Collection', children: (0, jsx_runtime_1.jsxs)("div", { className: 'grid gap-3 md:grid-cols-2', children: [(0, jsx_runtime_1.jsxs)(label_1.Label, { className: 'grid gap-1.5', children: [t('dynamicData.source'), (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: contentTypes.length === 0 && documentSourceOptions.length === 0, value: sourceType, onValueChange: (value) => {
784
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "grid gap-3", children: [(0, jsx_runtime_1.jsx)(PanelSection, { title: "Collection", children: (0, jsx_runtime_1.jsxs)("div", { className: "grid gap-3 md:grid-cols-2", children: [(0, jsx_runtime_1.jsxs)(label_1.Label, { className: "grid gap-1.5", children: [t('dynamicData.source'), (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: contentTypes.length === 0 && documentSourceOptions.length === 0, value: sourceType, onValueChange: (value) => {
847
785
  const documentSource = documentSourceOptions.find((option) => option.value === value);
848
786
  setSourceType(value);
849
787
  const nextFilterState = {
@@ -871,12 +809,12 @@ const ListBindingEditor = ({ contentTypes, documentContentType, rootDocumentCont
871
809
  },
872
810
  },
873
811
  });
874
- }, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'w-full', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: contentTypes.length > 0 || documentSourceOptions.length > 0
812
+ }, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: "w-full", children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: contentTypes.length > 0 || documentSourceOptions.length > 0
875
813
  ? 'Content type or document list'
876
- : 'No compatible sources' }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: (0, jsx_runtime_1.jsxs)(select_1.SelectGroup, { children: [documentSourceOptions.map((option) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: option.value, children: option.label }, option.value))), contentTypes.map((ct) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: ct.name, children: ct.name }, ct.name)))] }) })] })] }), (0, jsx_runtime_1.jsxs)(label_1.Label, { className: 'grid gap-1.5', children: [t('dynamicData.item'), (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: !sourceType || itemOptions.length === 0, value: itemName, onValueChange: (value) => {
814
+ : 'No compatible sources' }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: (0, jsx_runtime_1.jsxs)(select_1.SelectGroup, { children: [documentSourceOptions.map((option) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: option.value, children: option.label }, option.value))), contentTypes.map((ct) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: ct.name, children: ct.name }, ct.name)))] }) })] })] }), (0, jsx_runtime_1.jsxs)(label_1.Label, { className: "grid gap-1.5", children: [t('dynamicData.item'), (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: !sourceType || itemOptions.length === 0, value: itemName, onValueChange: (value) => {
877
815
  setItemName(value);
878
816
  emit({ itemName: value, map: {} });
879
- }, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'w-full', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: itemOptions.length > 0 ? 'Item type' : 'No item types' }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: (0, jsx_runtime_1.jsx)(select_1.SelectGroup, { children: itemOptions.map((item) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: item.name, children: item.name }, item.name))) }) })] })] })] }) }), selectedDocumentSource ? null : ((0, jsx_runtime_1.jsxs)(PanelSection, { title: 'Query', children: [(0, jsx_runtime_1.jsxs)("div", { className: 'grid grid-cols-[minmax(5rem,0.4fr)_minmax(0,1.2fr)_minmax(8rem,0.6fr)] items-end gap-3', children: [(0, jsx_runtime_1.jsxs)(label_1.Label, { className: 'grid gap-1.5', children: [t('dynamicData.limit'), (0, jsx_runtime_1.jsx)(input_1.Input, { type: 'number', min: 1, max: 100, value: String(binding?.query?.options?.limit ?? 10), onChange: (event) => emit({
817
+ }, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: "w-full", children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: itemOptions.length > 0 ? 'Item type' : 'No item types' }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: (0, jsx_runtime_1.jsx)(select_1.SelectGroup, { children: itemOptions.map((item) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: item.name, children: item.name }, item.name))) }) })] })] })] }) }), selectedDocumentSource ? null : ((0, jsx_runtime_1.jsxs)(PanelSection, { title: "Query", children: [(0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-[minmax(5rem,0.4fr)_minmax(0,1.2fr)_minmax(8rem,0.6fr)] items-end gap-3", children: [(0, jsx_runtime_1.jsxs)(label_1.Label, { className: "grid gap-1.5", children: [t('dynamicData.limit'), (0, jsx_runtime_1.jsx)(input_1.Input, { type: "number", min: 1, max: 100, value: String(binding?.query?.options?.limit ?? 10), onChange: (event) => emit({
880
818
  query: {
881
819
  ...binding?.query,
882
820
  options: {
@@ -884,19 +822,15 @@ const ListBindingEditor = ({ contentTypes, documentContentType, rootDocumentCont
884
822
  limit: Math.min(100, Math.max(1, Number(event.target.value || 10))),
885
823
  },
886
824
  },
887
- }) })] }), (0, jsx_runtime_1.jsxs)(label_1.Label, { className: 'grid min-w-0 gap-1.5', children: [t('dynamicData.sortBy'), (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: sortFieldOptions.length === 0, value: sortField || '__none__', onValueChange: (value) => emit({
825
+ }) })] }), (0, jsx_runtime_1.jsxs)(label_1.Label, { className: "grid min-w-0 gap-1.5", children: [t('dynamicData.sortBy'), (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: sortFieldOptions.length === 0, value: sortField || '__none__', onValueChange: (value) => emit({
888
826
  query: {
889
827
  ...binding?.query,
890
828
  options: {
891
829
  ...binding?.query?.options,
892
- sort: value === '__none__'
893
- ? undefined
894
- : { [value]: sortDirection },
830
+ sort: value === '__none__' ? undefined : { [value]: sortDirection },
895
831
  },
896
832
  },
897
- }), children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'w-full', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: sortFieldOptions.length > 0
898
- ? 'Sort by field'
899
- : 'No sortable fields' }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: (0, jsx_runtime_1.jsxs)(select_1.SelectGroup, { children: [(0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: '__none__', children: t('dynamicData.noSort') }), sortFieldOptions.map((item) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: item.value, children: item.label }, item.value)))] }) })] })] }), (0, jsx_runtime_1.jsxs)(label_1.Label, { className: 'grid gap-1.5', children: [t('dynamicData.direction'), (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: !sortField, value: sortDirection, onValueChange: (direction) => sortField
833
+ }), children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: "w-full", children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: sortFieldOptions.length > 0 ? 'Sort by field' : 'No sortable fields' }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: (0, jsx_runtime_1.jsxs)(select_1.SelectGroup, { children: [(0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: "__none__", children: t('dynamicData.noSort') }), sortFieldOptions.map((item) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: item.value, children: item.label }, item.value)))] }) })] })] }), (0, jsx_runtime_1.jsxs)(label_1.Label, { className: "grid gap-1.5", children: [t('dynamicData.direction'), (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: !sortField, value: sortDirection, onValueChange: (direction) => sortField
900
834
  ? emit({
901
835
  query: {
902
836
  ...binding?.query,
@@ -908,17 +842,16 @@ const ListBindingEditor = ({ contentTypes, documentContentType, rootDocumentCont
908
842
  },
909
843
  },
910
844
  })
911
- : undefined, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'w-full', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, {}) }), (0, jsx_runtime_1.jsxs)(select_1.SelectContent, { children: [(0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: 'asc', children: t('dynamicData.ascending') }), (0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: 'desc', children: t('dynamicData.descending') })] })] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: 'grid gap-3 rounded-md border border-border bg-background/60 p-3', children: [(0, jsx_runtime_1.jsxs)("div", { className: 'flex flex-wrap items-center justify-between gap-2', children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: 'text-sm font-medium', children: t('dynamicData.conditions') }), (0, jsx_runtime_1.jsx)("div", { className: 'text-xs text-muted-foreground', children: t('dynamicData.conditionsDescription') })] }), (0, jsx_runtime_1.jsxs)("div", { className: 'flex items-center gap-2', children: [filterState.conditions.length > 1 ? ((0, jsx_runtime_1.jsxs)(select_1.Select, { value: filterState.combinator, onValueChange: (combinator) => updateFilter({
845
+ : undefined, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: "w-full", children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, {}) }), (0, jsx_runtime_1.jsxs)(select_1.SelectContent, { children: [(0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: "asc", children: t('dynamicData.ascending') }), (0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: "desc", children: t('dynamicData.descending') })] })] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "grid gap-3 rounded-md border border-border bg-background/60 p-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-sm font-medium", children: t('dynamicData.conditions') }), (0, jsx_runtime_1.jsx)("div", { className: "text-xs text-muted-foreground", children: t('dynamicData.conditionsDescription') })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [filterState.conditions.length > 1 ? ((0, jsx_runtime_1.jsxs)(select_1.Select, { value: filterState.combinator, onValueChange: (combinator) => updateFilter({
912
846
  ...filterState,
913
847
  combinator: combinator,
914
- }), children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'h-8 w-36', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, {}) }), (0, jsx_runtime_1.jsxs)(select_1.SelectContent, { children: [(0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: 'and', children: t('dynamicData.matchAll') }), (0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: 'or', children: t('dynamicData.matchAny') })] })] })) : null, (0, jsx_runtime_1.jsxs)(button_1.Button, { type: 'button', size: 'sm', variant: 'outline', disabled: filterFieldOptions.length === 0 ||
915
- filterState.conditions.length >= 25, onClick: () => updateFilter({
848
+ }), children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: "h-8 w-36", children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, {}) }), (0, jsx_runtime_1.jsxs)(select_1.SelectContent, { children: [(0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: "and", children: t('dynamicData.matchAll') }), (0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: "or", children: t('dynamicData.matchAny') })] })] })) : null, (0, jsx_runtime_1.jsxs)(button_1.Button, { type: "button", size: "sm", variant: "outline", disabled: filterFieldOptions.length === 0 || filterState.conditions.length >= 25, onClick: () => updateFilter({
916
849
  ...filterState,
917
850
  conditions: [
918
851
  ...filterState.conditions,
919
852
  { field: '', operator: 'equals', value: '' },
920
853
  ],
921
- }), children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Plus, { className: 'h-4 w-4' }), t('dynamicData.addCondition')] })] })] }), filterState.conditions.length === 0 ? ((0, jsx_runtime_1.jsx)("div", { className: 'rounded-md border border-dashed border-border px-3 py-5 text-center text-sm text-muted-foreground', children: t('dynamicData.noConditions') })) : ((0, jsx_runtime_1.jsx)("div", { className: 'grid gap-2', children: filterState.conditions.map((condition, index) => {
854
+ }), children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Plus, { className: "h-4 w-4" }), t('dynamicData.addCondition')] })] })] }), filterState.conditions.length === 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "rounded-md border border-dashed border-border px-3 py-5 text-center text-sm text-muted-foreground", children: t('dynamicData.noConditions') })) : ((0, jsx_runtime_1.jsx)("div", { className: "grid gap-2", children: filterState.conditions.map((condition, index) => {
922
855
  const fieldOption = filterFieldOptions.find((option) => option.value === condition.field);
923
856
  const operatorOptions = getFilterOperatorOptions(fieldOption?.kind);
924
857
  const needsValue = operatorNeedsValue(condition.operator);
@@ -936,14 +869,14 @@ const ListBindingEditor = ({ contentTypes, documentContentType, rootDocumentCont
936
869
  condition.operator !== 'in' &&
937
870
  condition.operator !== 'notIn' &&
938
871
  currentItemValueOptions.length > 0;
939
- return ((0, jsx_runtime_1.jsxs)("div", { className: 'grid items-center gap-2 rounded-md border border-border bg-background p-2 sm:grid-cols-[1.2fr_1fr_1.8fr_auto]', children: [(0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: filterFieldOptions.length === 0, value: condition.field, onValueChange: (value) => {
872
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "grid items-center gap-2 rounded-md border border-border bg-background p-2 sm:grid-cols-[1.2fr_1fr_1.8fr_auto]", children: [(0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: filterFieldOptions.length === 0, value: condition.field, onValueChange: (value) => {
940
873
  const kind = filterFieldOptions.find((option) => option.value === value)?.kind;
941
874
  updateFilterCondition(index, {
942
875
  field: value,
943
876
  operator: defaultFilterOperator(kind),
944
877
  value: '',
945
878
  });
946
- }, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'w-full', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: t('dynamicData.field') }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: (0, jsx_runtime_1.jsx)(select_1.SelectGroup, { children: filterFieldOptions.map((item) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: item.value, children: item.label }, item.value))) }) })] }), (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: !condition.field, value: condition.operator, onValueChange: (operator) => updateFilterCondition(index, {
879
+ }, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: "w-full", children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: t('dynamicData.field') }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: (0, jsx_runtime_1.jsx)(select_1.SelectGroup, { children: filterFieldOptions.map((item) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: item.value, children: item.label }, item.value))) }) })] }), (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: !condition.field, value: condition.operator, onValueChange: (operator) => updateFilterCondition(index, {
947
880
  ...condition,
948
881
  operator: operator,
949
882
  valueSource: operator === 'in' || operator === 'notIn'
@@ -954,40 +887,35 @@ const ListBindingEditor = ({ contentTypes, documentContentType, rootDocumentCont
954
887
  ? ''
955
888
  : condition.value
956
889
  : '',
957
- }), children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'w-full', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: t('dynamicData.operator') }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: (0, jsx_runtime_1.jsx)(select_1.SelectGroup, { children: operatorOptions.map((option) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: option.value, children: option.label }, option.value))) }) })] }), needsValue ? ((0, jsx_runtime_1.jsxs)("div", { className: 'grid grid-cols-[minmax(7rem,0.7fr)_minmax(0,1fr)] gap-2', children: [(0, jsx_runtime_1.jsxs)(select_1.Select, { value: condition.valueSource ?? 'literal', onValueChange: (valueSource) => updateFilterCondition(index, {
890
+ }), children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: "w-full", children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: t('dynamicData.operator') }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: (0, jsx_runtime_1.jsx)(select_1.SelectGroup, { children: operatorOptions.map((option) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: option.value, children: option.label }, option.value))) }) })] }), needsValue ? ((0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-[minmax(7rem,0.7fr)_minmax(0,1fr)] gap-2", children: [(0, jsx_runtime_1.jsxs)(select_1.Select, { value: condition.valueSource ?? 'literal', onValueChange: (valueSource) => updateFilterCondition(index, {
958
891
  ...condition,
959
892
  valueSource: valueSource,
960
893
  value: '',
961
- }), children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'w-full', "aria-label": 'Value source', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, {}) }), (0, jsx_runtime_1.jsxs)(select_1.SelectContent, { children: [(0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: 'literal', children: t('dynamicData.fixedValue') }), allowsCurrentDocumentValue ? ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: currentItemContentType
962
- ? 'document'
963
- : 'current', children: t('dynamicData.currentDocument') })) : null, allowsCurrentItemValue ? ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: 'current', children: t('dynamicData.currentItem') })) : null] })] }), condition.valueSource === 'current' ||
894
+ }), children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: "w-full", "aria-label": "Value source", children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, {}) }), (0, jsx_runtime_1.jsxs)(select_1.SelectContent, { children: [(0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: "literal", children: t('dynamicData.fixedValue') }), allowsCurrentDocumentValue ? ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: currentItemContentType ? 'document' : 'current', children: t('dynamicData.currentDocument') })) : null, allowsCurrentItemValue ? ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: "current", children: t('dynamicData.currentItem') })) : null] })] }), condition.valueSource === 'current' ||
964
895
  condition.valueSource === 'document' ? ((0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: !condition.field, value: condition.value, onValueChange: (value) => updateFilterCondition(index, {
965
896
  ...condition,
966
897
  value,
967
- }), children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'w-full', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: t('dynamicData.currentField') }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: (0, jsx_runtime_1.jsx)(select_1.SelectGroup, { children: currentValueOptions.map((option) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: option.value, children: option.label }, option.value))) }) })] })) : ((0, jsx_runtime_1.jsx)(input_1.Input, { type: fieldOption?.kind === 'number' &&
898
+ }), children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: "w-full", children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: t('dynamicData.currentField') }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: (0, jsx_runtime_1.jsx)(select_1.SelectGroup, { children: currentValueOptions.map((option) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: option.value, children: option.label }, option.value))) }) })] })) : ((0, jsx_runtime_1.jsx)(input_1.Input, { type: fieldOption?.kind === 'number' &&
968
899
  condition.operator !== 'in' &&
969
900
  condition.operator !== 'notIn'
970
901
  ? 'number'
971
- : 'text', value: condition.value, disabled: !condition.field, placeholder: condition.operator === 'in' ||
972
- condition.operator === 'notIn'
902
+ : 'text', value: condition.value, disabled: !condition.field, placeholder: condition.operator === 'in' || condition.operator === 'notIn'
973
903
  ? 'Comma-separated values'
974
904
  : 'Value', onChange: (event) => updateFilterCondition(index, {
975
905
  ...condition,
976
906
  value: event.target.value,
977
- }) }))] })) : ((0, jsx_runtime_1.jsx)("div", { className: 'h-9 rounded-md border border-dashed border-border bg-muted/30' })), (0, jsx_runtime_1.jsxs)(button_1.Button, { type: 'button', size: 'icon', variant: 'ghost', className: 'size-9 text-muted-foreground hover:text-destructive', onClick: () => updateFilter({
907
+ }) }))] })) : ((0, jsx_runtime_1.jsx)("div", { className: "h-9 rounded-md border border-dashed border-border bg-muted/30" })), (0, jsx_runtime_1.jsxs)(button_1.Button, { type: "button", size: "icon", variant: "ghost", className: "size-9 text-muted-foreground hover:text-destructive", onClick: () => updateFilter({
978
908
  ...filterState,
979
909
  conditions: filterState.conditions.filter((_, conditionIndex) => conditionIndex !== index),
980
- }), children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Trash2, { className: 'h-4 w-4' }), (0, jsx_runtime_1.jsx)("span", { className: 'sr-only', children: t('dynamicData.removeCondition') })] })] }, `${index}-${condition.field}`));
981
- }) }))] })] })), (0, jsx_runtime_1.jsx)(PanelSection, { title: 'Mapping', children: (0, jsx_runtime_1.jsx)("div", { className: 'grid gap-2', children: targetFields.map(([targetField, targetFieldConfig]) => {
910
+ }), children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Trash2, { className: "h-4 w-4" }), (0, jsx_runtime_1.jsx)("span", { className: "sr-only", children: t('dynamicData.removeCondition') })] })] }, `${index}-${condition.field}`));
911
+ }) }))] })] })), (0, jsx_runtime_1.jsx)(PanelSection, { title: "Mapping", children: (0, jsx_runtime_1.jsx)("div", { className: "grid gap-2", children: targetFields.map(([targetField, targetFieldConfig]) => {
982
912
  const source = binding?.map?.[targetField];
983
913
  const summary = mappingSourceSummary(source, selectedSource?.name ?? 'Source');
984
914
  const summaryMode = isNestedListSource(source)
985
915
  ? t('dynamicData.nestedList')
986
916
  : summary.mode;
987
917
  const isOpen = openMappingField === targetField;
988
- return ((0, jsx_runtime_1.jsx)(collapsible_1.Collapsible, { open: isOpen, onOpenChange: (open) => setOpenMappingField(open ? targetField : null), children: (0, jsx_runtime_1.jsxs)("div", { className: 'overflow-hidden rounded-md border border-border bg-background/70 transition-colors hover:border-foreground/20', children: [(0, jsx_runtime_1.jsx)(collapsible_1.CollapsibleTrigger, { asChild: true, children: (0, jsx_runtime_1.jsxs)("button", { type: 'button', disabled: !selectedSource, className: 'group grid w-full grid-cols-[minmax(6rem,0.45fr)_auto_minmax(0,1fr)_auto] items-center gap-3 px-3 py-2.5 text-left outline-none transition-colors hover:bg-muted/50 focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50', children: [(0, jsx_runtime_1.jsx)("span", { className: 'truncate text-sm font-semibold', children: targetField }), (0, jsx_runtime_1.jsx)(badge_1.Badge, { variant: source ? 'secondary' : 'outline', className: 'max-w-40 truncate', children: summaryMode }), (0, jsx_runtime_1.jsx)("span", { className: 'truncate text-sm text-muted-foreground', children: selectedSource
989
- ? summary.detail
990
- : 'Select a source collection first' }), (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronRight, { className: 'h-4 w-4 text-muted-foreground transition-transform group-data-[state=open]:rotate-90' }), (0, jsx_runtime_1.jsx)("span", { className: 'sr-only', children: t('dynamicData.configureMapping', { name: targetField }) })] }) }), (0, jsx_runtime_1.jsx)(collapsible_1.CollapsibleContent, { children: (0, jsx_runtime_1.jsx)("div", { className: 'border-t border-border bg-muted/20 p-3', children: selectedSource ? ((0, jsx_runtime_1.jsx)(MappingSourceEditor, { contentTypes: contentTypes, rootDocumentContentType: rootDocumentContentType, currentSource: selectedSource, targetField: targetFieldConfig, source: source, onChange: (nextSource) => {
918
+ return ((0, jsx_runtime_1.jsx)(collapsible_1.Collapsible, { open: isOpen, onOpenChange: (open) => setOpenMappingField(open ? targetField : null), children: (0, jsx_runtime_1.jsxs)("div", { className: "overflow-hidden rounded-md border border-border bg-background/70 transition-colors hover:border-foreground/20", children: [(0, jsx_runtime_1.jsx)(collapsible_1.CollapsibleTrigger, { asChild: true, children: (0, jsx_runtime_1.jsxs)("button", { type: "button", disabled: !selectedSource, className: "group grid w-full grid-cols-[minmax(6rem,0.45fr)_auto_minmax(0,1fr)_auto] items-center gap-3 px-3 py-2.5 text-left outline-none transition-colors hover:bg-muted/50 focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50", children: [(0, jsx_runtime_1.jsx)("span", { className: "truncate text-sm font-semibold", children: targetField }), (0, jsx_runtime_1.jsx)(badge_1.Badge, { variant: source ? 'secondary' : 'outline', className: "max-w-40 truncate", children: summaryMode }), (0, jsx_runtime_1.jsx)("span", { className: "truncate text-sm text-muted-foreground", children: selectedSource ? summary.detail : 'Select a source collection first' }), (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronRight, { className: "h-4 w-4 text-muted-foreground transition-transform group-data-[state=open]:rotate-90" }), (0, jsx_runtime_1.jsx)("span", { className: "sr-only", children: t('dynamicData.configureMapping', { name: targetField }) })] }) }), (0, jsx_runtime_1.jsx)(collapsible_1.CollapsibleContent, { children: (0, jsx_runtime_1.jsx)("div", { className: "border-t border-border bg-muted/20 p-3", children: selectedSource ? ((0, jsx_runtime_1.jsx)(MappingSourceEditor, { contentTypes: contentTypes, rootDocumentContentType: rootDocumentContentType, currentSource: selectedSource, targetField: targetFieldConfig, source: source, onChange: (nextSource) => {
991
919
  const map = { ...(binding?.map ?? {}) };
992
920
  if (nextSource)
993
921
  map[targetField] = nextSource;
@@ -997,12 +925,32 @@ const ListBindingEditor = ({ contentTypes, documentContentType, rootDocumentCont
997
925
  } })) : null }) })] }) }, targetField));
998
926
  }) }) })] }));
999
927
  };
928
+ const StructuredArrayBindingEditor = ({ contentTypes, fieldContentTypes, documentContentType, currentDocumentSourceEnabled, field, fieldBinding, listBinding, onFieldChange, onListChange, }) => {
929
+ const t = (0, i18n_1.useTranslations)();
930
+ const [mode, setMode] = (0, react_1.useState)(listBinding ? 'list' : 'field');
931
+ (0, react_1.useEffect)(() => {
932
+ if (listBinding)
933
+ setMode('list');
934
+ else if (fieldBinding)
935
+ setMode('field');
936
+ }, [fieldBinding, listBinding]);
937
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "grid gap-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "grid max-w-sm content-start gap-1.5", children: [(0, jsx_runtime_1.jsx)(ControlLabel, { help: t('dynamicData.nestedListHelp'), children: t('dynamicData.mappingMode') }), (0, jsx_runtime_1.jsxs)(select_1.Select, { value: mode, onValueChange: (value) => {
938
+ if (value === 'list') {
939
+ setMode('list');
940
+ onListChange(undefined);
941
+ return;
942
+ }
943
+ setMode('field');
944
+ onFieldChange(undefined);
945
+ }, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: "w-full", children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, {}) }), (0, jsx_runtime_1.jsxs)(select_1.SelectContent, { children: [(0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: "field", children: t('dynamicData.directField') }), (0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: "list", children: t('dynamicData.nestedList') })] })] })] }), mode === 'list' ? ((0, jsx_runtime_1.jsx)(ListBindingEditor, { contentTypes: contentTypes, documentContentType: documentContentType, rootDocumentContentType: documentContentType, currentDocumentSourceEnabled: currentDocumentSourceEnabled, field: field, binding: listBinding, onChange: onListChange })) : ((0, jsx_runtime_1.jsx)(FieldBindingEditor, { contentTypes: fieldContentTypes, documentContentType: documentContentType, currentDocumentSourceEnabled: currentDocumentSourceEnabled, targetField: field, binding: fieldBinding, onChange: onFieldChange }))] }));
946
+ };
1000
947
  const DynamicDataControl = ({ contentType, documentContentType, fieldName, field, contentTypes, bindings, onChange, open, onOpenChange, mode = 'full', }) => {
1001
948
  const t = (0, i18n_1.useTranslations)();
1002
949
  const [internalOpen, setInternalOpen] = (0, react_1.useState)(false);
1003
950
  const [draftBindings, setDraftBindings] = (0, react_1.useState)(() => cloneDynamicBindings(bindings));
1004
951
  const wasOpenRef = (0, react_1.useRef)(open ?? internalOpen);
1005
- const list = isListField(field);
952
+ const list = (0, exports.isMappableDynamicListField)(field);
953
+ const structuredArray = list && field.config.capabilities.dynamic?.collection === 'homogeneous';
1006
954
  const isOpen = open ?? internalOpen;
1007
955
  (0, react_1.useEffect)(() => {
1008
956
  if (mode !== 'dialog')
@@ -1038,9 +986,14 @@ const DynamicDataControl = ({ contentType, documentContentType, fieldName, field
1038
986
  : sourceContentTypes.filter((sourceContentType) => sourceContentType.name !== contentType.name);
1039
987
  const fieldBinding = activeBindings?.fields?.[fieldName];
1040
988
  const listBinding = activeBindings?.lists?.[fieldName];
1041
- const bound = list ? !!listBinding : !!fieldBinding;
989
+ const bound = structuredArray
990
+ ? !!fieldBinding || !!listBinding
991
+ : list
992
+ ? !!listBinding
993
+ : !!fieldBinding;
994
+ const usesListBinding = list && !!listBinding;
1042
995
  const summary = bindingSummary({
1043
- list,
996
+ list: usesListBinding,
1044
997
  fieldBinding,
1045
998
  listBinding,
1046
999
  documentContentTypeName: currentDocumentContentType.name,
@@ -1067,7 +1020,44 @@ const DynamicDataControl = ({ contentType, documentContentType, fieldName, field
1067
1020
  lists: Object.keys(lists).length ? lists : undefined,
1068
1021
  });
1069
1022
  };
1070
- const clearBinding = () => list ? updateListBinding(undefined) : updateFieldBinding(undefined);
1023
+ const updateStructuredFieldBinding = (binding) => {
1024
+ const fields = { ...(activeBindings?.fields ?? {}) };
1025
+ const lists = { ...(activeBindings?.lists ?? {}) };
1026
+ if (binding)
1027
+ fields[fieldName] = binding;
1028
+ else
1029
+ delete fields[fieldName];
1030
+ delete lists[fieldName];
1031
+ commitBindings({
1032
+ ...(activeBindings ?? {}),
1033
+ fields: Object.keys(fields).length ? fields : undefined,
1034
+ lists: Object.keys(lists).length ? lists : undefined,
1035
+ });
1036
+ };
1037
+ const updateStructuredListBinding = (binding) => {
1038
+ const fields = { ...(activeBindings?.fields ?? {}) };
1039
+ const lists = { ...(activeBindings?.lists ?? {}) };
1040
+ delete fields[fieldName];
1041
+ if (binding)
1042
+ lists[fieldName] = binding;
1043
+ else
1044
+ delete lists[fieldName];
1045
+ commitBindings({
1046
+ ...(activeBindings ?? {}),
1047
+ fields: Object.keys(fields).length ? fields : undefined,
1048
+ lists: Object.keys(lists).length ? lists : undefined,
1049
+ });
1050
+ };
1051
+ const clearBinding = () => {
1052
+ if (structuredArray) {
1053
+ updateStructuredListBinding(undefined);
1054
+ return;
1055
+ }
1056
+ if (list)
1057
+ updateListBinding(undefined);
1058
+ else
1059
+ updateFieldBinding(undefined);
1060
+ };
1071
1061
  const triggerLabel = bound ? 'Edit dynamic data link' : 'Link dynamic data';
1072
1062
  const helpDescription = list
1073
1063
  ? 'Dynamic data fills this list from another content source. Use it when modules should stay synced with page, route, or related content instead of being edited manually here.'
@@ -1080,23 +1070,23 @@ const DynamicDataControl = ({ contentType, documentContentType, fieldName, field
1080
1070
  onChange(cleanDynamicBindings(draftBindings));
1081
1071
  setOpen(false);
1082
1072
  };
1083
- const trigger = ((0, jsx_runtime_1.jsxs)("div", { className: 'flex min-w-0 items-center gap-1.5', children: [(0, jsx_runtime_1.jsxs)(tooltip_1.Tooltip, { children: [(0, jsx_runtime_1.jsx)(tooltip_1.TooltipTrigger, { asChild: true, children: (0, jsx_runtime_1.jsx)("button", { type: 'button', className: 'min-w-0 cursor-pointer rounded-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring', onClick: () => setOpen((value) => !value), children: bound && summary ? ((0, jsx_runtime_1.jsxs)(badge_1.Badge, { variant: 'secondary', className: 'max-w-80 min-w-0 gap-1.5 rounded-md px-2 py-1 hover:bg-secondary/80', children: [list ? ((0, jsx_runtime_1.jsx)(lucide_react_1.ListFilter, { className: 'h-3.5 w-3.5 shrink-0' })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.Link2, { className: 'h-3.5 w-3.5 shrink-0' })), (0, jsx_runtime_1.jsx)("span", { className: 'truncate', children: summary })] })) : ((0, jsx_runtime_1.jsxs)(badge_1.Badge, { variant: 'outline', className: 'gap-1.5 rounded-md px-2 py-1 text-muted-foreground', children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Cable, { className: 'h-3.5 w-3.5' }), t('dynamicData.notLinked')] })) }) }), (0, jsx_runtime_1.jsx)(tooltip_1.TooltipContent, { side: 'top', sideOffset: 6, children: triggerLabel })] }), bound ? ((0, jsx_runtime_1.jsxs)(tooltip_1.Tooltip, { children: [(0, jsx_runtime_1.jsx)(tooltip_1.TooltipTrigger, { asChild: true, children: (0, jsx_runtime_1.jsxs)(button_1.Button, { type: 'button', size: 'icon', variant: 'ghost', className: 'size-6', onClick: clearBinding, children: [(0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: 'h-4 w-4' }), (0, jsx_runtime_1.jsx)("span", { className: 'sr-only', children: t('dynamicData.clear') })] }) }), (0, jsx_runtime_1.jsx)(tooltip_1.TooltipContent, { side: 'top', sideOffset: 6, children: t('dynamicData.clearLink') })] })) : null] }));
1084
- const editor = list ? ((0, jsx_runtime_1.jsx)(ListBindingEditor, { contentTypes: sourceContentTypes, documentContentType: currentDocumentContentType, rootDocumentContentType: currentDocumentContentType, currentDocumentSourceEnabled: currentDocumentSourceEnabled, field: field, binding: listBinding, onChange: updateListBinding })) : ((0, jsx_runtime_1.jsx)(FieldBindingEditor, { contentTypes: fieldSourceContentTypes, documentContentType: currentDocumentContentType, currentDocumentSourceEnabled: currentDocumentSourceEnabled, targetField: field, binding: fieldBinding, onChange: updateFieldBinding }));
1085
- const panel = isOpen ? ((0, jsx_runtime_1.jsx)("div", { className: 'rounded-md border border-border bg-background p-4 shadow-sm', children: editor })) : null;
1073
+ const trigger = ((0, jsx_runtime_1.jsxs)("div", { className: "flex min-w-0 items-center gap-1.5", children: [(0, jsx_runtime_1.jsxs)(tooltip_1.Tooltip, { children: [(0, jsx_runtime_1.jsx)(tooltip_1.TooltipTrigger, { asChild: true, children: (0, jsx_runtime_1.jsx)("button", { type: "button", className: "min-w-0 cursor-pointer rounded-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", onClick: () => setOpen((value) => !value), children: bound && summary ? ((0, jsx_runtime_1.jsxs)(badge_1.Badge, { variant: "secondary", className: "max-w-80 min-w-0 gap-1.5 rounded-md px-2 py-1 hover:bg-secondary/80", children: [usesListBinding ? ((0, jsx_runtime_1.jsx)(lucide_react_1.ListFilter, { className: "h-3.5 w-3.5 shrink-0" })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.Link2, { className: "h-3.5 w-3.5 shrink-0" })), (0, jsx_runtime_1.jsx)("span", { className: "truncate", children: summary })] })) : ((0, jsx_runtime_1.jsxs)(badge_1.Badge, { variant: "outline", className: "gap-1.5 rounded-md px-2 py-1 text-muted-foreground", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Cable, { className: "h-3.5 w-3.5" }), t('dynamicData.notLinked')] })) }) }), (0, jsx_runtime_1.jsx)(tooltip_1.TooltipContent, { side: "top", sideOffset: 6, children: triggerLabel })] }), bound ? ((0, jsx_runtime_1.jsxs)(tooltip_1.Tooltip, { children: [(0, jsx_runtime_1.jsx)(tooltip_1.TooltipTrigger, { asChild: true, children: (0, jsx_runtime_1.jsxs)(button_1.Button, { type: "button", size: "icon", variant: "ghost", className: "size-6", onClick: clearBinding, children: [(0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "h-4 w-4" }), (0, jsx_runtime_1.jsx)("span", { className: "sr-only", children: t('dynamicData.clear') })] }) }), (0, jsx_runtime_1.jsx)(tooltip_1.TooltipContent, { side: "top", sideOffset: 6, children: t('dynamicData.clearLink') })] })) : null] }));
1074
+ const editor = structuredArray ? ((0, jsx_runtime_1.jsx)(StructuredArrayBindingEditor, { contentTypes: sourceContentTypes, fieldContentTypes: fieldSourceContentTypes, documentContentType: currentDocumentContentType, currentDocumentSourceEnabled: currentDocumentSourceEnabled, field: field, fieldBinding: fieldBinding, listBinding: listBinding, onFieldChange: updateStructuredFieldBinding, onListChange: updateStructuredListBinding })) : list ? ((0, jsx_runtime_1.jsx)(ListBindingEditor, { contentTypes: sourceContentTypes, documentContentType: currentDocumentContentType, rootDocumentContentType: currentDocumentContentType, currentDocumentSourceEnabled: currentDocumentSourceEnabled, field: field, binding: listBinding, onChange: updateListBinding })) : ((0, jsx_runtime_1.jsx)(FieldBindingEditor, { contentTypes: fieldSourceContentTypes, documentContentType: currentDocumentContentType, currentDocumentSourceEnabled: currentDocumentSourceEnabled, targetField: field, binding: fieldBinding, onChange: updateFieldBinding }));
1075
+ const panel = isOpen ? ((0, jsx_runtime_1.jsx)("div", { className: "rounded-md border border-border bg-background p-4 shadow-sm", children: editor })) : null;
1086
1076
  const dialog = ((0, jsx_runtime_1.jsx)(dialog_1.Dialog, { open: isOpen, onOpenChange: (value) => {
1087
1077
  if (value) {
1088
1078
  setOpen(true);
1089
1079
  return;
1090
1080
  }
1091
1081
  cancelDialogChanges();
1092
- }, children: (0, jsx_runtime_1.jsxs)(dialog_1.DialogContent, { className: 'max-h-[85vh] w-screen max-w-5xl! overflow-y-auto', children: [(0, jsx_runtime_1.jsxs)(dialog_1.DialogHeader, { children: [(0, jsx_runtime_1.jsxs)(dialog_1.DialogTitle, { className: 'flex items-center gap-2', children: [t('dynamicData.title'), (0, jsx_runtime_1.jsx)(lucide_react_1.HelpCircle, { className: 'h-4 w-4 text-muted-foreground' })] }), (0, jsx_runtime_1.jsx)(dialog_1.DialogDescription, { className: 'max-w-2xl leading-relaxed', children: helpDescription })] }), editor, (0, jsx_runtime_1.jsxs)(dialog_1.DialogFooter, { children: [(0, jsx_runtime_1.jsx)(button_1.Button, { type: 'button', variant: 'outline', onClick: cancelDialogChanges, children: t('common.cancel') }), (0, jsx_runtime_1.jsx)(button_1.Button, { type: 'button', onClick: saveDialogChanges, children: t('common.save') })] })] }) }));
1082
+ }, children: (0, jsx_runtime_1.jsxs)(dialog_1.DialogContent, { className: "max-h-[85vh] w-screen max-w-5xl! overflow-y-auto", children: [(0, jsx_runtime_1.jsxs)(dialog_1.DialogHeader, { children: [(0, jsx_runtime_1.jsxs)(dialog_1.DialogTitle, { className: "flex items-center gap-2", children: [t('dynamicData.title'), (0, jsx_runtime_1.jsx)(lucide_react_1.HelpCircle, { className: "h-4 w-4 text-muted-foreground" })] }), (0, jsx_runtime_1.jsx)(dialog_1.DialogDescription, { className: "max-w-2xl leading-relaxed", children: helpDescription })] }), editor, (0, jsx_runtime_1.jsxs)(dialog_1.DialogFooter, { children: [(0, jsx_runtime_1.jsx)(button_1.Button, { type: "button", variant: "outline", onClick: cancelDialogChanges, children: t('common.cancel') }), (0, jsx_runtime_1.jsx)(button_1.Button, { type: "button", onClick: saveDialogChanges, children: t('common.save') })] })] }) }));
1093
1083
  if (mode === 'trigger')
1094
1084
  return trigger;
1095
1085
  if (mode === 'panel')
1096
1086
  return panel;
1097
1087
  if (mode === 'dialog')
1098
1088
  return dialog;
1099
- return ((0, jsx_runtime_1.jsxs)("div", { className: 'grid min-w-0 gap-2', children: [(0, jsx_runtime_1.jsx)("div", { className: 'flex min-w-0 justify-end', children: trigger }), panel] }));
1089
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "grid min-w-0 gap-2", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex min-w-0 justify-end", children: trigger }), panel] }));
1100
1090
  };
1101
1091
  exports.DynamicDataControl = DynamicDataControl;
1102
1092
  //# sourceMappingURL=DynamicDataControl.js.map