@elytracms/studio 0.0.1

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 (558) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +3 -0
  3. package/convex/assets.ts +107 -0
  4. package/convex/auth.config.ts +15 -0
  5. package/convex/auth.ts +50 -0
  6. package/convex/cliTokens.ts +63 -0
  7. package/convex/cms.ts +174 -0
  8. package/convex/content.ts +316 -0
  9. package/convex/delivery.ts +266 -0
  10. package/convex/functions.ts +35 -0
  11. package/convex/graphs.ts +51 -0
  12. package/convex/guard.ts +67 -0
  13. package/convex/http.ts +30 -0
  14. package/convex/members.ts +83 -0
  15. package/convex/publishing.ts +102 -0
  16. package/convex/references.ts +168 -0
  17. package/convex/schema.ts +173 -0
  18. package/convex/sync.ts +322 -0
  19. package/convex/tsconfig.json +12 -0
  20. package/convex/users.ts +23 -0
  21. package/convex/webhooks.ts +85 -0
  22. package/dist/components/assets/asset-library.d.ts +14 -0
  23. package/dist/components/assets/asset-library.js +191 -0
  24. package/dist/components/assets/asset-library.js.map +1 -0
  25. package/dist/components/assets/asset-metadata.d.ts +34 -0
  26. package/dist/components/assets/asset-metadata.js +40 -0
  27. package/dist/components/assets/asset-metadata.js.map +1 -0
  28. package/dist/components/assets/asset-search.d.ts +7 -0
  29. package/dist/components/assets/asset-search.js +12 -0
  30. package/dist/components/assets/asset-search.js.map +1 -0
  31. package/dist/components/assets/asset-selection.d.ts +17 -0
  32. package/dist/components/assets/asset-selection.js +33 -0
  33. package/dist/components/assets/asset-selection.js.map +1 -0
  34. package/dist/components/assets/assets-store.d.ts +51 -0
  35. package/dist/components/assets/assets-store.js +153 -0
  36. package/dist/components/assets/assets-store.js.map +1 -0
  37. package/dist/components/auth-context.d.ts +38 -0
  38. package/dist/components/auth-context.js +88 -0
  39. package/dist/components/auth-context.js.map +1 -0
  40. package/dist/components/backend-gate.d.ts +19 -0
  41. package/dist/components/backend-gate.js +63 -0
  42. package/dist/components/backend-gate.js.map +1 -0
  43. package/dist/components/breadcrumb-context.d.ts +39 -0
  44. package/dist/components/breadcrumb-context.js +38 -0
  45. package/dist/components/breadcrumb-context.js.map +1 -0
  46. package/dist/components/builder/blocks-model.d.ts +80 -0
  47. package/dist/components/builder/blocks-model.js +181 -0
  48. package/dist/components/builder/blocks-model.js.map +1 -0
  49. package/dist/components/builder/blocks-panel.d.ts +44 -0
  50. package/dist/components/builder/blocks-panel.js +147 -0
  51. package/dist/components/builder/blocks-panel.js.map +1 -0
  52. package/dist/components/builder/builder-store.d.ts +69 -0
  53. package/dist/components/builder/builder-store.js +294 -0
  54. package/dist/components/builder/builder-store.js.map +1 -0
  55. package/dist/components/builder/canvas-stylesheet.d.ts +4 -0
  56. package/dist/components/builder/canvas-stylesheet.js +24 -0
  57. package/dist/components/builder/canvas-stylesheet.js.map +1 -0
  58. package/dist/components/builder/canvas.d.ts +8 -0
  59. package/dist/components/builder/canvas.js +723 -0
  60. package/dist/components/builder/canvas.js.map +1 -0
  61. package/dist/components/builder/clipboard-actions.d.ts +93 -0
  62. package/dist/components/builder/clipboard-actions.js +246 -0
  63. package/dist/components/builder/clipboard-actions.js.map +1 -0
  64. package/dist/components/builder/composition-field-editor.d.ts +11 -0
  65. package/dist/components/builder/composition-field-editor.js +150 -0
  66. package/dist/components/builder/composition-field-editor.js.map +1 -0
  67. package/dist/components/builder/composition-scope.d.ts +16 -0
  68. package/dist/components/builder/composition-scope.js +7 -0
  69. package/dist/components/builder/composition-scope.js.map +1 -0
  70. package/dist/components/builder/drag-session.d.ts +41 -0
  71. package/dist/components/builder/drag-session.js +51 -0
  72. package/dist/components/builder/drag-session.js.map +1 -0
  73. package/dist/components/builder/fixture-thumbnail.d.ts +18 -0
  74. package/dist/components/builder/fixture-thumbnail.js +97 -0
  75. package/dist/components/builder/fixture-thumbnail.js.map +1 -0
  76. package/dist/components/builder/inline-edit.d.ts +142 -0
  77. package/dist/components/builder/inline-edit.js +136 -0
  78. package/dist/components/builder/inline-edit.js.map +1 -0
  79. package/dist/components/builder/insert-context.d.ts +14 -0
  80. package/dist/components/builder/insert-context.js +65 -0
  81. package/dist/components/builder/insert-context.js.map +1 -0
  82. package/dist/components/builder/insert-menu.d.ts +9 -0
  83. package/dist/components/builder/insert-menu.js +9 -0
  84. package/dist/components/builder/insert-menu.js.map +1 -0
  85. package/dist/components/builder/layout-inspector.d.ts +14 -0
  86. package/dist/components/builder/layout-inspector.js +84 -0
  87. package/dist/components/builder/layout-inspector.js.map +1 -0
  88. package/dist/components/builder/node-factory.d.ts +17 -0
  89. package/dist/components/builder/node-factory.js +90 -0
  90. package/dist/components/builder/node-factory.js.map +1 -0
  91. package/dist/components/builder/page-tree.d.ts +3 -0
  92. package/dist/components/builder/page-tree.js +207 -0
  93. package/dist/components/builder/page-tree.js.map +1 -0
  94. package/dist/components/builder/property-inspector.d.ts +1 -0
  95. package/dist/components/builder/property-inspector.js +233 -0
  96. package/dist/components/builder/property-inspector.js.map +1 -0
  97. package/dist/components/builder/rich-text-toolbar.d.ts +4 -0
  98. package/dist/components/builder/rich-text-toolbar.js +104 -0
  99. package/dist/components/builder/rich-text-toolbar.js.map +1 -0
  100. package/dist/components/builder/spacing-handles.d.ts +22 -0
  101. package/dist/components/builder/spacing-handles.js +213 -0
  102. package/dist/components/builder/spacing-handles.js.map +1 -0
  103. package/dist/components/cms/asset-picker.d.ts +12 -0
  104. package/dist/components/cms/asset-picker.js +60 -0
  105. package/dist/components/cms/asset-picker.js.map +1 -0
  106. package/dist/components/cms/bulk-actions.d.ts +60 -0
  107. package/dist/components/cms/bulk-actions.js +95 -0
  108. package/dist/components/cms/bulk-actions.js.map +1 -0
  109. package/dist/components/cms/bulk-bar.d.ts +23 -0
  110. package/dist/components/cms/bulk-bar.js +26 -0
  111. package/dist/components/cms/bulk-bar.js.map +1 -0
  112. package/dist/components/cms/cell-edit.d.ts +91 -0
  113. package/dist/components/cms/cell-edit.js +144 -0
  114. package/dist/components/cms/cell-edit.js.map +1 -0
  115. package/dist/components/cms/cell.d.ts +29 -0
  116. package/dist/components/cms/cell.js +127 -0
  117. package/dist/components/cms/cell.js.map +1 -0
  118. package/dist/components/cms/cms-index.d.ts +8 -0
  119. package/dist/components/cms/cms-index.js +23 -0
  120. package/dist/components/cms/cms-index.js.map +1 -0
  121. package/dist/components/cms/cms-store.d.ts +188 -0
  122. package/dist/components/cms/cms-store.js +702 -0
  123. package/dist/components/cms/cms-store.js.map +1 -0
  124. package/dist/components/cms/collection-table.d.ts +6 -0
  125. package/dist/components/cms/collection-table.js +250 -0
  126. package/dist/components/cms/collection-table.js.map +1 -0
  127. package/dist/components/cms/collections-sidebar.d.ts +9 -0
  128. package/dist/components/cms/collections-sidebar.js +25 -0
  129. package/dist/components/cms/collections-sidebar.js.map +1 -0
  130. package/dist/components/cms/detail-editor.d.ts +7 -0
  131. package/dist/components/cms/detail-editor.js +386 -0
  132. package/dist/components/cms/detail-editor.js.map +1 -0
  133. package/dist/components/cms/doc-state.d.ts +13 -0
  134. package/dist/components/cms/doc-state.js +18 -0
  135. package/dist/components/cms/doc-state.js.map +1 -0
  136. package/dist/components/cms/document-editor-context.d.ts +48 -0
  137. package/dist/components/cms/document-editor-context.js +23 -0
  138. package/dist/components/cms/document-editor-context.js.map +1 -0
  139. package/dist/components/cms/editable-cell.d.ts +22 -0
  140. package/dist/components/cms/editable-cell.js +176 -0
  141. package/dist/components/cms/editable-cell.js.map +1 -0
  142. package/dist/components/cms/field-control.d.ts +8 -0
  143. package/dist/components/cms/field-control.js +149 -0
  144. package/dist/components/cms/field-control.js.map +1 -0
  145. package/dist/components/cms/filter-builder.d.ts +12 -0
  146. package/dist/components/cms/filter-builder.js +84 -0
  147. package/dist/components/cms/filter-builder.js.map +1 -0
  148. package/dist/components/cms/import-export.d.ts +6 -0
  149. package/dist/components/cms/import-export.js +33 -0
  150. package/dist/components/cms/import-export.js.map +1 -0
  151. package/dist/components/cms/new-page-dialog.d.ts +22 -0
  152. package/dist/components/cms/new-page-dialog.js +42 -0
  153. package/dist/components/cms/new-page-dialog.js.map +1 -0
  154. package/dist/components/cms/reference-confirm.d.ts +25 -0
  155. package/dist/components/cms/reference-confirm.js +124 -0
  156. package/dist/components/cms/reference-confirm.js.map +1 -0
  157. package/dist/components/cms/relation-picker.d.ts +16 -0
  158. package/dist/components/cms/relation-picker.js +47 -0
  159. package/dist/components/cms/relation-picker.js.map +1 -0
  160. package/dist/components/cms/use-cell-edit.d.ts +33 -0
  161. package/dist/components/cms/use-cell-edit.js +125 -0
  162. package/dist/components/cms/use-cell-edit.js.map +1 -0
  163. package/dist/components/cms/versions-model.d.ts +15 -0
  164. package/dist/components/cms/versions-model.js +23 -0
  165. package/dist/components/cms/versions-model.js.map +1 -0
  166. package/dist/components/cms/versions-pane.d.ts +14 -0
  167. package/dist/components/cms/versions-pane.js +86 -0
  168. package/dist/components/cms/versions-pane.js.map +1 -0
  169. package/dist/components/cms/view-bar.d.ts +11 -0
  170. package/dist/components/cms/view-bar.js +80 -0
  171. package/dist/components/cms/view-bar.js.map +1 -0
  172. package/dist/components/collab/collab-context.d.ts +34 -0
  173. package/dist/components/collab/collab-context.js +52 -0
  174. package/dist/components/collab/collab-context.js.map +1 -0
  175. package/dist/components/collab/collab-seed.d.ts +27 -0
  176. package/dist/components/collab/collab-seed.js +42 -0
  177. package/dist/components/collab/collab-seed.js.map +1 -0
  178. package/dist/components/components/component-detail.d.ts +9 -0
  179. package/dist/components/components/component-detail.js +30 -0
  180. package/dist/components/components/component-detail.js.map +1 -0
  181. package/dist/components/components/component-status.d.ts +10 -0
  182. package/dist/components/components/component-status.js +30 -0
  183. package/dist/components/components/component-status.js.map +1 -0
  184. package/dist/components/components/components-index.d.ts +8 -0
  185. package/dist/components/components/components-index.js +42 -0
  186. package/dist/components/components/components-index.js.map +1 -0
  187. package/dist/components/components/field-inspector.d.ts +9 -0
  188. package/dist/components/components/field-inspector.js +38 -0
  189. package/dist/components/components/field-inspector.js.map +1 -0
  190. package/dist/components/components/fixture-runner.d.ts +10 -0
  191. package/dist/components/components/fixture-runner.js +24 -0
  192. package/dist/components/components/fixture-runner.js.map +1 -0
  193. package/dist/components/components/registry-browser.d.ts +4 -0
  194. package/dist/components/components/registry-browser.js +64 -0
  195. package/dist/components/components/registry-browser.js.map +1 -0
  196. package/dist/components/current-user-menu.d.ts +13 -0
  197. package/dist/components/current-user-menu.js +31 -0
  198. package/dist/components/current-user-menu.js.map +1 -0
  199. package/dist/components/dev-login-badge.d.ts +9 -0
  200. package/dist/components/dev-login-badge.js +18 -0
  201. package/dist/components/dev-login-badge.js.map +1 -0
  202. package/dist/components/extensions/extensions-view.d.ts +7 -0
  203. package/dist/components/extensions/extensions-view.js +126 -0
  204. package/dist/components/extensions/extensions-view.js.map +1 -0
  205. package/dist/components/guards.d.ts +27 -0
  206. package/dist/components/guards.js +46 -0
  207. package/dist/components/guards.js.map +1 -0
  208. package/dist/components/inspector/inspector-sidebar.d.ts +26 -0
  209. package/dist/components/inspector/inspector-sidebar.js +17 -0
  210. package/dist/components/inspector/inspector-sidebar.js.map +1 -0
  211. package/dist/components/operation-error.d.ts +17 -0
  212. package/dist/components/operation-error.js +54 -0
  213. package/dist/components/operation-error.js.map +1 -0
  214. package/dist/components/playground-badge.d.ts +10 -0
  215. package/dist/components/playground-badge.js +19 -0
  216. package/dist/components/playground-badge.js.map +1 -0
  217. package/dist/components/project-list.d.ts +15 -0
  218. package/dist/components/project-list.js +52 -0
  219. package/dist/components/project-list.js.map +1 -0
  220. package/dist/components/project-session.d.ts +46 -0
  221. package/dist/components/project-session.js +107 -0
  222. package/dist/components/project-session.js.map +1 -0
  223. package/dist/components/project-switcher.d.ts +11 -0
  224. package/dist/components/project-switcher.js +44 -0
  225. package/dist/components/project-switcher.js.map +1 -0
  226. package/dist/components/references/builder-deep-link.d.ts +12 -0
  227. package/dist/components/references/builder-deep-link.js +53 -0
  228. package/dist/components/references/builder-deep-link.js.map +1 -0
  229. package/dist/components/references/references-panel.d.ts +17 -0
  230. package/dist/components/references/references-panel.js +66 -0
  231. package/dist/components/references/references-panel.js.map +1 -0
  232. package/dist/components/routes/redirect-chain.d.ts +9 -0
  233. package/dist/components/routes/redirect-chain.js +16 -0
  234. package/dist/components/routes/redirect-chain.js.map +1 -0
  235. package/dist/components/routes/redirect-manager.d.ts +13 -0
  236. package/dist/components/routes/redirect-manager.js +24 -0
  237. package/dist/components/routes/redirect-manager.js.map +1 -0
  238. package/dist/components/routes/route-list.d.ts +35 -0
  239. package/dist/components/routes/route-list.js +69 -0
  240. package/dist/components/routes/route-list.js.map +1 -0
  241. package/dist/components/routes/routes-shell.d.ts +14 -0
  242. package/dist/components/routes/routes-shell.js +68 -0
  243. package/dist/components/routes/routes-shell.js.map +1 -0
  244. package/dist/components/section-nav.d.ts +17 -0
  245. package/dist/components/section-nav.js +33 -0
  246. package/dist/components/section-nav.js.map +1 -0
  247. package/dist/components/section-state.d.ts +24 -0
  248. package/dist/components/section-state.js +78 -0
  249. package/dist/components/section-state.js.map +1 -0
  250. package/dist/components/section-surface.d.ts +31 -0
  251. package/dist/components/section-surface.js +46 -0
  252. package/dist/components/section-surface.js.map +1 -0
  253. package/dist/components/sections.d.ts +38 -0
  254. package/dist/components/sections.js +72 -0
  255. package/dist/components/sections.js.map +1 -0
  256. package/dist/components/settings-form.d.ts +10 -0
  257. package/dist/components/settings-form.js +17 -0
  258. package/dist/components/settings-form.js.map +1 -0
  259. package/dist/components/studio-context.d.ts +22 -0
  260. package/dist/components/studio-context.js +48 -0
  261. package/dist/components/studio-context.js.map +1 -0
  262. package/dist/components/studio-project-screen.d.ts +19 -0
  263. package/dist/components/studio-project-screen.js +195 -0
  264. package/dist/components/studio-project-screen.js.map +1 -0
  265. package/dist/components/studio-shell.d.ts +18 -0
  266. package/dist/components/studio-shell.js +64 -0
  267. package/dist/components/studio-shell.js.map +1 -0
  268. package/dist/components/theme-context.d.ts +17 -0
  269. package/dist/components/theme-context.js +26 -0
  270. package/dist/components/theme-context.js.map +1 -0
  271. package/dist/components/workspace-gate.d.ts +12 -0
  272. package/dist/components/workspace-gate.js +27 -0
  273. package/dist/components/workspace-gate.js.map +1 -0
  274. package/dist/components/workspace-projects.d.ts +13 -0
  275. package/dist/components/workspace-projects.js +18 -0
  276. package/dist/components/workspace-projects.js.map +1 -0
  277. package/dist/lib/assets/delete-asset.d.ts +34 -0
  278. package/dist/lib/assets/delete-asset.js +34 -0
  279. package/dist/lib/assets/delete-asset.js.map +1 -0
  280. package/dist/lib/assets/image-dimensions.d.ts +18 -0
  281. package/dist/lib/assets/image-dimensions.js +26 -0
  282. package/dist/lib/assets/image-dimensions.js.map +1 -0
  283. package/dist/lib/assets/index.d.ts +9 -0
  284. package/dist/lib/assets/index.js +10 -0
  285. package/dist/lib/assets/index.js.map +1 -0
  286. package/dist/lib/assets/upload-state.d.ts +53 -0
  287. package/dist/lib/assets/upload-state.js +59 -0
  288. package/dist/lib/assets/upload-state.js.map +1 -0
  289. package/dist/lib/assets/upload.d.ts +56 -0
  290. package/dist/lib/assets/upload.js +125 -0
  291. package/dist/lib/assets/upload.js.map +1 -0
  292. package/dist/lib/auth/auth-adapter.d.ts +57 -0
  293. package/dist/lib/auth/auth-adapter.js +13 -0
  294. package/dist/lib/auth/auth-adapter.js.map +1 -0
  295. package/dist/lib/auth/convex-auth-adapter.d.ts +39 -0
  296. package/dist/lib/auth/convex-auth-adapter.js +171 -0
  297. package/dist/lib/auth/convex-auth-adapter.js.map +1 -0
  298. package/dist/lib/auth/dev-auto-login-adapter.d.ts +25 -0
  299. package/dist/lib/auth/dev-auto-login-adapter.js +40 -0
  300. package/dist/lib/auth/dev-auto-login-adapter.js.map +1 -0
  301. package/dist/lib/auth/index.d.ts +28 -0
  302. package/dist/lib/auth/index.js +61 -0
  303. package/dist/lib/auth/index.js.map +1 -0
  304. package/dist/lib/auth/local-auth-adapter.d.ts +57 -0
  305. package/dist/lib/auth/local-auth-adapter.js +78 -0
  306. package/dist/lib/auth/local-auth-adapter.js.map +1 -0
  307. package/dist/lib/auth/route-guard.d.ts +33 -0
  308. package/dist/lib/auth/route-guard.js +51 -0
  309. package/dist/lib/auth/route-guard.js.map +1 -0
  310. package/dist/lib/auth-errors.d.ts +42 -0
  311. package/dist/lib/auth-errors.js +74 -0
  312. package/dist/lib/auth-errors.js.map +1 -0
  313. package/dist/lib/bindings/section-bindings.d.ts +24 -0
  314. package/dist/lib/bindings/section-bindings.js +9 -0
  315. package/dist/lib/bindings/section-bindings.js.map +1 -0
  316. package/dist/lib/clipboard/index.d.ts +7 -0
  317. package/dist/lib/clipboard/index.js +8 -0
  318. package/dist/lib/clipboard/index.js.map +1 -0
  319. package/dist/lib/clipboard/os-clipboard.d.ts +46 -0
  320. package/dist/lib/clipboard/os-clipboard.js +105 -0
  321. package/dist/lib/clipboard/os-clipboard.js.map +1 -0
  322. package/dist/lib/clipboard/paste-issues.d.ts +34 -0
  323. package/dist/lib/clipboard/paste-issues.js +67 -0
  324. package/dist/lib/clipboard/paste-issues.js.map +1 -0
  325. package/dist/lib/clipboard/paste-target.d.ts +20 -0
  326. package/dist/lib/clipboard/paste-target.js +28 -0
  327. package/dist/lib/clipboard/paste-target.js.map +1 -0
  328. package/dist/lib/cms/published-documents.d.ts +30 -0
  329. package/dist/lib/cms/published-documents.js +75 -0
  330. package/dist/lib/cms/published-documents.js.map +1 -0
  331. package/dist/lib/cms-views/index.d.ts +9 -0
  332. package/dist/lib/cms-views/index.js +10 -0
  333. package/dist/lib/cms-views/index.js.map +1 -0
  334. package/dist/lib/cms-views/selection.d.ts +29 -0
  335. package/dist/lib/cms-views/selection.js +46 -0
  336. package/dist/lib/cms-views/selection.js.map +1 -0
  337. package/dist/lib/cms-views/view-model.d.ts +192 -0
  338. package/dist/lib/cms-views/view-model.js +353 -0
  339. package/dist/lib/cms-views/view-model.js.map +1 -0
  340. package/dist/lib/cms-views/views-store.d.ts +70 -0
  341. package/dist/lib/cms-views/views-store.js +129 -0
  342. package/dist/lib/cms-views/views-store.js.map +1 -0
  343. package/dist/lib/data/collection-content.d.ts +105 -0
  344. package/dist/lib/data/collection-content.js +196 -0
  345. package/dist/lib/data/collection-content.js.map +1 -0
  346. package/dist/lib/data/data-store.d.ts +97 -0
  347. package/dist/lib/data/data-store.js +205 -0
  348. package/dist/lib/data/data-store.js.map +1 -0
  349. package/dist/lib/data/index.d.ts +4 -0
  350. package/dist/lib/data/index.js +8 -0
  351. package/dist/lib/data/index.js.map +1 -0
  352. package/dist/lib/data/providers.d.ts +143 -0
  353. package/dist/lib/data/providers.js +255 -0
  354. package/dist/lib/data/providers.js.map +1 -0
  355. package/dist/lib/data/sample-capture.d.ts +30 -0
  356. package/dist/lib/data/sample-capture.js +70 -0
  357. package/dist/lib/data/sample-capture.js.map +1 -0
  358. package/dist/lib/data/sources-store.d.ts +42 -0
  359. package/dist/lib/data/sources-store.js +120 -0
  360. package/dist/lib/data/sources-store.js.map +1 -0
  361. package/dist/lib/dnd/drop-rules.d.ts +219 -0
  362. package/dist/lib/dnd/drop-rules.js +257 -0
  363. package/dist/lib/dnd/drop-rules.js.map +1 -0
  364. package/dist/lib/dnd/gap-drag.d.ts +66 -0
  365. package/dist/lib/dnd/gap-drag.js +95 -0
  366. package/dist/lib/dnd/gap-drag.js.map +1 -0
  367. package/dist/lib/locale/binding-fallback.d.ts +28 -0
  368. package/dist/lib/locale/binding-fallback.js +66 -0
  369. package/dist/lib/locale/binding-fallback.js.map +1 -0
  370. package/dist/lib/locale/fallback.d.ts +43 -0
  371. package/dist/lib/locale/fallback.js +52 -0
  372. package/dist/lib/locale/fallback.js.map +1 -0
  373. package/dist/lib/locale/index.d.ts +6 -0
  374. package/dist/lib/locale/index.js +7 -0
  375. package/dist/lib/locale/index.js.map +1 -0
  376. package/dist/lib/locale/locale-store.d.ts +40 -0
  377. package/dist/lib/locale/locale-store.js +61 -0
  378. package/dist/lib/locale/locale-store.js.map +1 -0
  379. package/dist/lib/locale/locale-switcher.d.ts +10 -0
  380. package/dist/lib/locale/locale-switcher.js +24 -0
  381. package/dist/lib/locale/locale-switcher.js.map +1 -0
  382. package/dist/lib/locale/route-variant.d.ts +14 -0
  383. package/dist/lib/locale/route-variant.js +11 -0
  384. package/dist/lib/locale/route-variant.js.map +1 -0
  385. package/dist/lib/locale/use-studio-locale.d.ts +10 -0
  386. package/dist/lib/locale/use-studio-locale.js +8 -0
  387. package/dist/lib/locale/use-studio-locale.js.map +1 -0
  388. package/dist/lib/operations/asset-repository.d.ts +15 -0
  389. package/dist/lib/operations/asset-repository.js +56 -0
  390. package/dist/lib/operations/asset-repository.js.map +1 -0
  391. package/dist/lib/operations/cms-persistence.d.ts +35 -0
  392. package/dist/lib/operations/cms-persistence.js +75 -0
  393. package/dist/lib/operations/cms-persistence.js.map +1 -0
  394. package/dist/lib/operations/graph-commands.d.ts +140 -0
  395. package/dist/lib/operations/graph-commands.js +86 -0
  396. package/dist/lib/operations/graph-commands.js.map +1 -0
  397. package/dist/lib/operations/graph-persistence.d.ts +27 -0
  398. package/dist/lib/operations/graph-persistence.js +35 -0
  399. package/dist/lib/operations/graph-persistence.js.map +1 -0
  400. package/dist/lib/operations/index.d.ts +13 -0
  401. package/dist/lib/operations/index.js +14 -0
  402. package/dist/lib/operations/index.js.map +1 -0
  403. package/dist/lib/operations/operations-package.d.ts +6 -0
  404. package/dist/lib/operations/operations-package.js +7 -0
  405. package/dist/lib/operations/operations-package.js.map +1 -0
  406. package/dist/lib/operations/persist-queue.d.ts +16 -0
  407. package/dist/lib/operations/persist-queue.js +18 -0
  408. package/dist/lib/operations/persist-queue.js.map +1 -0
  409. package/dist/lib/operations/session-hydration.d.ts +84 -0
  410. package/dist/lib/operations/session-hydration.js +112 -0
  411. package/dist/lib/operations/session-hydration.js.map +1 -0
  412. package/dist/lib/operations/studio-operations.d.ts +59 -0
  413. package/dist/lib/operations/studio-operations.js +92 -0
  414. package/dist/lib/operations/studio-operations.js.map +1 -0
  415. package/dist/lib/persistence/backend-mode.d.ts +69 -0
  416. package/dist/lib/persistence/backend-mode.js +120 -0
  417. package/dist/lib/persistence/backend-mode.js.map +1 -0
  418. package/dist/lib/persistence/convex-adapter.d.ts +34 -0
  419. package/dist/lib/persistence/convex-adapter.js +681 -0
  420. package/dist/lib/persistence/convex-adapter.js.map +1 -0
  421. package/dist/lib/persistence/convex-blob-storage.d.ts +57 -0
  422. package/dist/lib/persistence/convex-blob-storage.js +97 -0
  423. package/dist/lib/persistence/convex-blob-storage.js.map +1 -0
  424. package/dist/lib/persistence/convex-client.d.ts +19 -0
  425. package/dist/lib/persistence/convex-client.js +40 -0
  426. package/dist/lib/persistence/convex-client.js.map +1 -0
  427. package/dist/lib/persistence/index.d.ts +30 -0
  428. package/dist/lib/persistence/index.js +60 -0
  429. package/dist/lib/persistence/index.js.map +1 -0
  430. package/dist/lib/persona/labels.d.ts +23 -0
  431. package/dist/lib/persona/labels.js +122 -0
  432. package/dist/lib/persona/labels.js.map +1 -0
  433. package/dist/lib/rail.d.ts +11 -0
  434. package/dist/lib/rail.js +26 -0
  435. package/dist/lib/rail.js.map +1 -0
  436. package/dist/lib/references/impact.d.ts +64 -0
  437. package/dist/lib/references/impact.js +62 -0
  438. package/dist/lib/references/impact.js.map +1 -0
  439. package/dist/lib/references/index.d.ts +7 -0
  440. package/dist/lib/references/index.js +8 -0
  441. package/dist/lib/references/index.js.map +1 -0
  442. package/dist/lib/references/reference-model.d.ts +125 -0
  443. package/dist/lib/references/reference-model.js +242 -0
  444. package/dist/lib/references/reference-model.js.map +1 -0
  445. package/dist/lib/references/references-store.d.ts +65 -0
  446. package/dist/lib/references/references-store.js +221 -0
  447. package/dist/lib/references/references-store.js.map +1 -0
  448. package/dist/lib/registry/index.d.ts +65 -0
  449. package/dist/lib/registry/index.js +114 -0
  450. package/dist/lib/registry/index.js.map +1 -0
  451. package/dist/lib/registry/preview.d.ts +15 -0
  452. package/dist/lib/registry/preview.js +110 -0
  453. package/dist/lib/registry/preview.js.map +1 -0
  454. package/dist/lib/registry/project-components.d.ts +16 -0
  455. package/dist/lib/registry/project-components.js +152 -0
  456. package/dist/lib/registry/project-components.js.map +1 -0
  457. package/dist/lib/routing/index.d.ts +10 -0
  458. package/dist/lib/routing/index.js +11 -0
  459. package/dist/lib/routing/index.js.map +1 -0
  460. package/dist/lib/routing/routing-analysis.d.ts +26 -0
  461. package/dist/lib/routing/routing-analysis.js +37 -0
  462. package/dist/lib/routing/routing-analysis.js.map +1 -0
  463. package/dist/lib/routing/routing-store.d.ts +50 -0
  464. package/dist/lib/routing/routing-store.js +72 -0
  465. package/dist/lib/routing/routing-store.js.map +1 -0
  466. package/dist/lib/starters/kit-session.d.ts +5 -0
  467. package/dist/lib/starters/kit-session.js +17 -0
  468. package/dist/lib/starters/kit-session.js.map +1 -0
  469. package/dist/lib/theme.d.ts +21 -0
  470. package/dist/lib/theme.js +32 -0
  471. package/dist/lib/theme.js.map +1 -0
  472. package/dist/lib/utils.d.ts +11 -0
  473. package/dist/lib/utils.js +28 -0
  474. package/dist/lib/utils.js.map +1 -0
  475. package/dist/lib/webhooks/config.d.ts +15 -0
  476. package/dist/lib/webhooks/config.js +64 -0
  477. package/dist/lib/webhooks/config.js.map +1 -0
  478. package/dist/lib/webhooks/dispatcher.d.ts +67 -0
  479. package/dist/lib/webhooks/dispatcher.js +61 -0
  480. package/dist/lib/webhooks/dispatcher.js.map +1 -0
  481. package/dist/lib/webhooks/index.d.ts +11 -0
  482. package/dist/lib/webhooks/index.js +10 -0
  483. package/dist/lib/webhooks/index.js.map +1 -0
  484. package/dist/lib/webhooks/signing.d.ts +15 -0
  485. package/dist/lib/webhooks/signing.js +24 -0
  486. package/dist/lib/webhooks/signing.js.map +1 -0
  487. package/dist/lib/webhooks/tags.d.ts +25 -0
  488. package/dist/lib/webhooks/tags.js +173 -0
  489. package/dist/lib/webhooks/tags.js.map +1 -0
  490. package/dist/lib/working-graph.d.ts +82 -0
  491. package/dist/lib/working-graph.js +113 -0
  492. package/dist/lib/working-graph.js.map +1 -0
  493. package/dist/lib/workspace/index.d.ts +109 -0
  494. package/dist/lib/workspace/index.js +206 -0
  495. package/dist/lib/workspace/index.js.map +1 -0
  496. package/dist/lib/workspace/switcher-source.d.ts +39 -0
  497. package/dist/lib/workspace/switcher-source.js +23 -0
  498. package/dist/lib/workspace/switcher-source.js.map +1 -0
  499. package/dist/lib/workspace/workspace-source.d.ts +47 -0
  500. package/dist/lib/workspace/workspace-source.js +67 -0
  501. package/dist/lib/workspace/workspace-source.js.map +1 -0
  502. package/dist/router/index.d.ts +32 -0
  503. package/dist/router/index.js +32 -0
  504. package/dist/router/index.js.map +1 -0
  505. package/dist/router/match.d.ts +75 -0
  506. package/dist/router/match.js +87 -0
  507. package/dist/router/match.js.map +1 -0
  508. package/dist/router/search.d.ts +22 -0
  509. package/dist/router/search.js +16 -0
  510. package/dist/router/search.js.map +1 -0
  511. package/dist/ui/avatar.d.ts +17 -0
  512. package/dist/ui/avatar.js +38 -0
  513. package/dist/ui/avatar.js.map +1 -0
  514. package/dist/ui/badge.d.ts +9 -0
  515. package/dist/ui/badge.js +23 -0
  516. package/dist/ui/badge.js.map +1 -0
  517. package/dist/ui/button.d.ts +11 -0
  518. package/dist/ui/button.js +30 -0
  519. package/dist/ui/button.js.map +1 -0
  520. package/dist/ui/card.d.ts +11 -0
  521. package/dist/ui/card.js +23 -0
  522. package/dist/ui/card.js.map +1 -0
  523. package/dist/ui/dialog.d.ts +12 -0
  524. package/dist/ui/dialog.js +27 -0
  525. package/dist/ui/dialog.js.map +1 -0
  526. package/dist/ui/dropdown-menu.d.ts +15 -0
  527. package/dist/ui/dropdown-menu.js +24 -0
  528. package/dist/ui/dropdown-menu.js.map +1 -0
  529. package/dist/ui/field.d.ts +15 -0
  530. package/dist/ui/field.js +14 -0
  531. package/dist/ui/field.js.map +1 -0
  532. package/dist/ui/index.d.ts +14 -0
  533. package/dist/ui/index.js +15 -0
  534. package/dist/ui/index.js.map +1 -0
  535. package/dist/ui/input.d.ts +3 -0
  536. package/dist/ui/input.js +7 -0
  537. package/dist/ui/input.js.map +1 -0
  538. package/dist/ui/inspector.d.ts +18 -0
  539. package/dist/ui/inspector.js +14 -0
  540. package/dist/ui/inspector.js.map +1 -0
  541. package/dist/ui/layout.d.ts +45 -0
  542. package/dist/ui/layout.js +48 -0
  543. package/dist/ui/layout.js.map +1 -0
  544. package/dist/ui/panel.d.ts +12 -0
  545. package/dist/ui/panel.js +20 -0
  546. package/dist/ui/panel.js.map +1 -0
  547. package/dist/ui/separator.d.ts +6 -0
  548. package/dist/ui/separator.js +7 -0
  549. package/dist/ui/separator.js.map +1 -0
  550. package/dist/ui/toolbar.d.ts +9 -0
  551. package/dist/ui/toolbar.js +16 -0
  552. package/dist/ui/toolbar.js.map +1 -0
  553. package/dist/ui/typography.d.ts +50 -0
  554. package/dist/ui/typography.js +43 -0
  555. package/dist/ui/typography.js.map +1 -0
  556. package/package.json +149 -0
  557. package/src/styles/studio.css +101 -0
  558. package/src/styles/tokens.css +63 -0
@@ -0,0 +1,42 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { STUDIO_PROJECT_ROUTE, studioPath, useNavigate } from '@elytracms/studio/router';
3
+ import { useState } from 'react';
4
+ import { Button, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, Field, Input, Stack, } from '@elytracms/studio/ui';
5
+ import { useCms } from './cms-store';
6
+ /**
7
+ * Create a page in ONE action (EC-192). Pages are documents in the `page`
8
+ * collection (EC-187): this dialog mints the page document (stable slug id,
9
+ * `cms.createPage`) and opens the new page's editor.
10
+ *
11
+ * EC-207 ("routes as code"): creating a page no longer persists an addressing
12
+ * route to the backend — routes are authored in `elytra.config.ts` and read
13
+ * from the resolved config, never written to or read from the DB. The page's
14
+ * URL is bound by a route in the consuming repo's `cms/routes.ts`, so this
15
+ * dialog only creates the page document.
16
+ */
17
+ export function NewPageDialog({ projectId, open, onOpenChange, }) {
18
+ const cms = useCms();
19
+ const navigate = useNavigate();
20
+ const [name, setName] = useState('');
21
+ function reset() {
22
+ setName('');
23
+ }
24
+ function handleOpenChange(next) {
25
+ if (!next)
26
+ reset();
27
+ onOpenChange(next);
28
+ }
29
+ function submit(event) {
30
+ event.preventDefault();
31
+ if (name.trim() === '')
32
+ return;
33
+ const ref = cms.createPage({ name: name.trim() });
34
+ handleOpenChange(false);
35
+ void navigate({
36
+ to: STUDIO_PROJECT_ROUTE,
37
+ params: { projectId, _splat: studioPath.cmsDocument('page', ref.id) },
38
+ });
39
+ }
40
+ return (_jsx(Dialog, { open: open, onOpenChange: handleOpenChange, children: _jsxs(DialogContent, { children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "New page" }), _jsx(DialogDescription, { children: "Give the page a name. You can design it next; its address is set in elytra.config.ts." })] }), _jsxs("form", { onSubmit: submit, children: [_jsx(Stack, { gap: "3", children: _jsx(Field, { label: "Name", htmlFor: "new-page-name", required: true, children: _jsx(Input, { id: "new-page-name", value: name, onChange: (event) => setName(event.target.value), placeholder: "About us", autoFocus: true, required: true }) }) }), _jsxs(DialogFooter, { className: "mt-4", children: [_jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => handleOpenChange(false), children: "Cancel" }), _jsx(Button, { type: "submit", size: "sm", disabled: name.trim() === '', "data-testid": "create-page", children: "Create page" })] })] })] }) }));
41
+ }
42
+ //# sourceMappingURL=new-page-dialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"new-page-dialog.js","sourceRoot":"","sources":["../../../src/components/cms/new-page-dialog.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,oBAAoB,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AACxF,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAEhC,OAAO,EACL,MAAM,EACN,MAAM,EACN,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,KAAK,EACL,KAAK,EACL,KAAK,GACN,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEpC;;;;;;;;;;GAUG;AACH,MAAM,UAAU,aAAa,CAAC,EAC5B,SAAS,EACT,IAAI,EACJ,YAAY,GAWb;IACC,MAAM,GAAG,GAAG,MAAM,EAAE,CAAA;IACpB,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAA;IAC9B,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAA;IAEpC,SAAS,KAAK;QACZ,OAAO,CAAC,EAAE,CAAC,CAAA;IACb,CAAC;IAED,SAAS,gBAAgB,CAAC,IAAa;QACrC,IAAI,CAAC,IAAI;YAAE,KAAK,EAAE,CAAA;QAClB,YAAY,CAAC,IAAI,CAAC,CAAA;IACpB,CAAC;IAED,SAAS,MAAM,CAAC,KAAgB;QAC9B,KAAK,CAAC,cAAc,EAAE,CAAA;QACtB,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,OAAM;QAC9B,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;QACjD,gBAAgB,CAAC,KAAK,CAAC,CAAA;QACvB,KAAK,QAAQ,CAAC;YACZ,EAAE,EAAE,oBAAoB;YACxB,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,EAAE;SACtE,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,CACL,KAAC,MAAM,IAAC,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,gBAAgB,YAChD,MAAC,aAAa,eACZ,MAAC,YAAY,eACX,KAAC,WAAW,2BAAuB,EACnC,KAAC,iBAAiB,wGAEE,IACP,EACf,gBAAM,QAAQ,EAAE,MAAM,aACpB,KAAC,KAAK,IAAC,GAAG,EAAC,GAAG,YACZ,KAAC,KAAK,IAAC,KAAK,EAAC,MAAM,EAAC,OAAO,EAAC,eAAe,EAAC,QAAQ,kBAClD,KAAC,KAAK,IACJ,EAAE,EAAC,eAAe,EAClB,KAAK,EAAE,IAAI,EACX,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EAChD,WAAW,EAAC,UAAU,EACtB,SAAS,QACT,QAAQ,SACR,GACI,GACF,EACR,MAAC,YAAY,IAAC,SAAS,EAAC,MAAM,aAC5B,KAAC,MAAM,IAAC,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAC,OAAO,EAAC,IAAI,EAAC,IAAI,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,uBAE7E,EACT,KAAC,MAAM,IACL,IAAI,EAAC,QAAQ,EACb,IAAI,EAAC,IAAI,EACT,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,iBAChB,aAAa,4BAGlB,IACI,IACV,IACO,GACT,CACV,CAAA;AACH,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { DocumentRef } from '@elytracms/cms-core';
2
+ import type { ReferenceAction, ReferenceEntryView } from '@elytracms/studio/lib/references';
3
+ export declare function ReferenceConfirmDialog({ projectId, action, targets, open, busy, onOpenChange, onConfirm, }: {
4
+ projectId: string;
5
+ action: ReferenceAction;
6
+ /** The documents being acted on (a stable snapshot taken when opening). */
7
+ targets: readonly DocumentRef[];
8
+ open: boolean;
9
+ busy?: boolean;
10
+ onOpenChange: (open: boolean) => void;
11
+ onConfirm: () => void;
12
+ }): import("react").JSX.Element;
13
+ /**
14
+ * The shared EC-173 impact rows: one deep-linked row per broken inbound
15
+ * reference, strict-blocking ones flagged. Rendered by the document
16
+ * confirmation dialog (above) and the asset-delete dialog (EC-202) alike — both
17
+ * reduce to "these places reference the thing you're removing", so both lean on
18
+ * the same row + deep-link rendering (which already handles asset link kinds).
19
+ */
20
+ export declare function ReferenceImpactRows({ projectId, broken, blocking, onNavigate, }: {
21
+ projectId: string;
22
+ broken: readonly ReferenceEntryView[];
23
+ blocking?: readonly ReferenceEntryView[];
24
+ onNavigate: () => void;
25
+ }): import("react").JSX.Element;
@@ -0,0 +1,124 @@
1
+ import { jsxs as _jsxs, Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
+ import { Link, STUDIO_PROJECT_ROUTE, studioPath } from '@elytracms/studio/router';
3
+ import { AlertTriangle, ShieldAlert } from 'lucide-react';
4
+ import { useEffect, useMemo, useState } from 'react';
5
+ import { documentKey } from '@elytracms/cms-core';
6
+ import { buildReferenceImpact, loadInboundReferenceViews } from '@elytracms/studio/lib/references';
7
+ import { Badge, Button, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, Row, Stack, Text, } from '@elytracms/studio/ui';
8
+ import { useCms } from './cms-store';
9
+ const ACTION_LABELS = {
10
+ unpublish: 'Unpublish',
11
+ delete: 'Delete',
12
+ };
13
+ export function ReferenceConfirmDialog({ projectId, action, targets, open, busy = false, onOpenChange, onConfirm, }) {
14
+ const cms = useCms();
15
+ const [status, setStatus] = useState('loading');
16
+ const [impact, setImpact] = useState(null);
17
+ // A stable identity for the acted-on set, so the effect re-runs exactly
18
+ // when the selection (not the array instance) changes.
19
+ const targetsKey = targets.map((ref) => documentKey(ref)).join('\n');
20
+ useEffect(() => {
21
+ if (!open || targets.length === 0)
22
+ return;
23
+ let cancelled = false;
24
+ setStatus('loading');
25
+ setImpact(null);
26
+ void (async () => {
27
+ try {
28
+ // Queued session mutations (and the persisted baseline) must land
29
+ // before the pre-flight query — the index is maintained on write.
30
+ await cms.ensurePersistedBaseline();
31
+ await cms.flushPersistence();
32
+ const views = await loadInboundReferenceViews(projectId, targets);
33
+ if (cancelled)
34
+ return;
35
+ setImpact(buildReferenceImpact(cms.collections, action, views));
36
+ setStatus('ready');
37
+ }
38
+ catch {
39
+ // The index being unreachable must not trap the editor: degrade to a
40
+ // plain confirm with an explicit "could not check" warning.
41
+ if (!cancelled)
42
+ setStatus('unavailable');
43
+ }
44
+ })();
45
+ return () => {
46
+ cancelled = true;
47
+ };
48
+ // `targetsKey` stands in for `targets` (stable identity for the acted-on set).
49
+ }, [open, action, targetsKey, projectId]);
50
+ const actionLabel = ACTION_LABELS[action];
51
+ const subject = useMemo(() => {
52
+ if (targets.length === 1) {
53
+ const ref = targets[0];
54
+ return `“${cms.titleOf(ref)}”`;
55
+ }
56
+ return `${targets.length} documents`;
57
+ }, [targets, cms]);
58
+ const blocked = status === 'ready' && (impact?.totalBlocking ?? 0) > 0;
59
+ const totalBroken = impact?.totalBroken ?? 0;
60
+ return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { "data-testid": "reference-confirm", className: "max-h-[80vh] overflow-y-auto", children: [_jsxs(DialogHeader, { children: [_jsxs(DialogTitle, { children: [actionLabel, " ", subject, "?"] }), _jsx(DialogDescription, { "data-testid": "reference-confirm-summary", children: status === 'loading' ? ('Checking inbound references…') : status === 'unavailable' ? ('Inbound references could not be checked — the reference index is unreachable.') : blocked ? (_jsxs(_Fragment, { children: ["Blocked: ", impact.totalBlocking, ' ', impact.totalBlocking === 1 ? 'strict reference prevents' : 'strict references prevent', ' ', "this. Remove the references below first."] })) : totalBroken === 0 ? (_jsxs(_Fragment, { children: ["Not referenced anywhere.", action === 'delete'
61
+ ? ` This permanently deletes ${targets.length === 1 ? 'the document' : `the ${targets.length} selected documents`}.`
62
+ : ''] })) : (_jsxs(_Fragment, { children: ["You can ", action, " \u2014 ", impactSummary(targets.length, totalBroken), " will show a fallback until fixed. Each one becomes a visible validation issue."] })) })] }), status === 'ready' && impact !== null && totalBroken > 0 ? (_jsx(ImpactList, { projectId: projectId, impact: impact, onNavigate: () => onOpenChange(false) })) : null, status === 'unavailable' ? (_jsxs(Row, { gap: "2", "data-testid": "reference-confirm-unavailable", children: [_jsx(AlertTriangle, { className: "size-4 shrink-0 text-warning" }), _jsx(Text, { size: "xs", tone: "muted", children: "Proceeding is allowed, but affected places cannot be listed right now." })] })) : null, _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "outline", "data-testid": "reference-confirm-cancel", onClick: () => onOpenChange(false), children: "Cancel" }), _jsx(Button, { variant: action === 'delete' ? 'destructive' : 'default', disabled: status === 'loading' || blocked || busy, "data-testid": "reference-confirm-proceed", onClick: onConfirm, children: totalBroken > 0 && !blocked ? `${actionLabel} anyway` : actionLabel })] })] }) }));
63
+ }
64
+ function impactSummary(targetCount, totalBroken) {
65
+ const places = `${totalBroken} ${totalBroken === 1 ? 'place' : 'places'}`;
66
+ // The bulk aggregate: "N documents, M inbound references will break."
67
+ return targetCount > 1 ? `${targetCount} documents are affected; ${places}` : places;
68
+ }
69
+ /**
70
+ * The enumerated impact: flat for a single target, grouped per target for
71
+ * bulk selections (per-item detail, EC-169 honesty rules).
72
+ */
73
+ function ImpactList({ projectId, impact, onNavigate, }) {
74
+ const affected = impact.documents.filter((doc) => doc.broken.length > 0);
75
+ return (_jsx(Stack, { gap: "3", "data-testid": "reference-confirm-impact", children: affected.map((doc) => (_jsx(ImpactGroup, { projectId: projectId, doc: doc, grouped: impact.documents.length > 1, onNavigate: onNavigate }, documentKey(doc.ref)))) }));
76
+ }
77
+ function ImpactGroup({ projectId, doc, grouped, onNavigate, }) {
78
+ const cms = useCms();
79
+ const blockingKeys = new Set(doc.blocking.map((entry) => entry.key));
80
+ return (_jsxs(Stack, { gap: "2", "data-testid": `reference-confirm-doc-${doc.ref.id}`, children: [grouped ? (_jsxs(Row, { gap: "2", children: [_jsx(Text, { size: "xs", weight: "semibold", tone: "muted", className: "uppercase tracking-wide", children: cms.titleOf(doc.ref) }), _jsx(Badge, { variant: "outline", children: doc.broken.length })] })) : null, doc.broken.map((entry) => (_jsx(ImpactEntryRow, { projectId: projectId, entry: entry, blocking: blockingKeys.has(entry.key), onNavigate: onNavigate }, entry.key)))] }));
81
+ }
82
+ /**
83
+ * The shared EC-173 impact rows: one deep-linked row per broken inbound
84
+ * reference, strict-blocking ones flagged. Rendered by the document
85
+ * confirmation dialog (above) and the asset-delete dialog (EC-202) alike — both
86
+ * reduce to "these places reference the thing you're removing", so both lean on
87
+ * the same row + deep-link rendering (which already handles asset link kinds).
88
+ */
89
+ export function ReferenceImpactRows({ projectId, broken, blocking = [], onNavigate, }) {
90
+ const blockingKeys = new Set(blocking.map((entry) => entry.key));
91
+ return (_jsx(Stack, { gap: "2", "data-testid": "reference-impact-rows", children: broken.map((entry) => (_jsx(ImpactEntryRow, { projectId: projectId, entry: entry, blocking: blockingKeys.has(entry.key), onNavigate: onNavigate }, entry.key))) }));
92
+ }
93
+ /**
94
+ * One affected place: the EC-172 labels with a working deep link to the exact
95
+ * field/node, the entry kind, draft/published visibility — and a strict
96
+ * marker when this entry is what blocks the action.
97
+ */
98
+ function ImpactEntryRow({ projectId, entry, blocking, onNavigate, }) {
99
+ return (_jsxs(Row, { gap: "2", className: blocking
100
+ ? 'rounded-md border border-destructive/50 bg-destructive/5 px-2.5 py-2'
101
+ : 'rounded-md border border-border/70 bg-background/40 px-2.5 py-2', "data-testid": "reference-confirm-entry", children: [_jsxs(Stack, { gap: "1", className: "min-w-0 flex-1", children: [_jsx(ImpactDeepLink, { projectId: projectId, link: entry.sourceLink, label: entry.sourceLabel, primary: true, onNavigate: onNavigate }), _jsxs(Row, { gap: "1", className: "min-w-0", children: [_jsx(Text, { size: "xs", tone: "muted", className: "shrink-0", children: "at" }), _jsx(ImpactDeepLink, { projectId: projectId, link: entry.sourceLink, label: entry.locationLabel, onNavigate: onNavigate })] })] }), blocking ? (_jsxs(Badge, { variant: "error", "data-testid": "reference-confirm-strict", children: [_jsx(ShieldAlert, { className: "size-3" }), " strict"] })) : null, _jsx(Badge, { variant: "outline", className: "shrink-0", children: entry.kindLabel }), _jsxs(Row, { gap: "1", className: "shrink-0", children: [entry.draft ? _jsx(Badge, { variant: "warning", children: "draft" }) : null, entry.published ? _jsx(Badge, { variant: "success", children: "published" }) : null] })] }));
102
+ }
103
+ /** A deep link to the exact source location; closes the dialog on navigate. */
104
+ function ImpactDeepLink({ projectId, link, label, primary = false, onNavigate, }) {
105
+ const className = primary
106
+ ? 'min-w-0 truncate text-sm font-medium text-foreground hover:text-primary hover:underline'
107
+ : 'min-w-0 truncate text-xs text-muted-foreground hover:text-primary hover:underline';
108
+ if (link === null) {
109
+ return primary ? (_jsx(Text, { size: "sm", weight: "medium", className: "min-w-0 truncate", children: label })) : (_jsx(Text, { size: "xs", tone: "muted", className: "min-w-0 truncate", children: label }));
110
+ }
111
+ switch (link.kind) {
112
+ case 'cms-field':
113
+ return (_jsx(Link, { to: STUDIO_PROJECT_ROUTE, params: { projectId, _splat: studioPath.cmsDocument(link.collectionId, link.documentId) }, search: link.fieldPath !== undefined ? { field: link.fieldPath } : {}, className: className, "data-testid": "reference-confirm-link", onClick: onNavigate, children: label }));
114
+ case 'builder-node':
115
+ // The builder redirect (EC-187) only reads `?page=`; the page-graph-only
116
+ // `node` has no home in the document editor and is dropped.
117
+ return (_jsx(Link, { to: STUDIO_PROJECT_ROUTE, params: { projectId, _splat: studioPath.builder() }, search: link.pageId !== undefined ? { page: link.pageId } : {}, className: className, "data-testid": "reference-confirm-link", onClick: onNavigate, children: label }));
118
+ case 'component':
119
+ return (_jsx(Link, { to: STUDIO_PROJECT_ROUTE, params: { projectId, _splat: studioPath.component(link.componentId) }, className: className, "data-testid": "reference-confirm-link", onClick: onNavigate, children: label }));
120
+ case 'asset':
121
+ return (_jsx(Link, { to: STUDIO_PROJECT_ROUTE, params: { projectId, _splat: studioPath.assets() }, search: { asset: link.assetId }, className: className, "data-testid": "reference-confirm-link", onClick: onNavigate, children: label }));
122
+ }
123
+ }
124
+ //# sourceMappingURL=reference-confirm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reference-confirm.js","sourceRoot":"","sources":["../../../src/components/cms/reference-confirm.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { DocumentRef } from '@elytracms/cms-core';
2
+ /** Pick related document(s) from a target collection (brief §8.4, EC-074). */
3
+ export declare function RelationPicker({ targetCollection, cardinality, value, open, onOpenChange, onChange, excludeIds, }: {
4
+ targetCollection: string;
5
+ cardinality: 'one' | 'many';
6
+ value: DocumentRef[];
7
+ open: boolean;
8
+ onOpenChange: (open: boolean) => void;
9
+ onChange: (refs: DocumentRef[]) => void;
10
+ /**
11
+ * Document ids to omit from the candidate list (EC-218): a `parent` self-relation
12
+ * passes the editing document plus its descendants, so a page can never be set
13
+ * as its own ancestor (which would form a cycle).
14
+ */
15
+ excludeIds?: ReadonlySet<string>;
16
+ }): import("react").JSX.Element;
@@ -0,0 +1,47 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { Check, Search } from 'lucide-react';
3
+ import { useEffect, useState } from 'react';
4
+ import { Badge, Button, Code, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, Input, Row, Spacer, Text, } from '@elytracms/studio/ui';
5
+ import { cn } from '@elytracms/studio/lib/utils';
6
+ import { useCms } from './cms-store';
7
+ /** Pick related document(s) from a target collection (brief §8.4, EC-074). */
8
+ export function RelationPicker({ targetCollection, cardinality, value, open, onOpenChange, onChange, excludeIds, }) {
9
+ const cms = useCms();
10
+ const [query, setQuery] = useState('');
11
+ const [selected, setSelected] = useState(value);
12
+ // Seed selection only on open transitions — `value` is a fresh array each
13
+ // parent render, so depending on it would reset in-progress multi-selection.
14
+ useEffect(() => {
15
+ if (open) {
16
+ setSelected(value);
17
+ setQuery('');
18
+ }
19
+ }, [open]);
20
+ const candidates = cms.documentsOf(targetCollection).filter((d) => {
21
+ if (excludeIds?.has(d.id))
22
+ return false;
23
+ if (!query.trim())
24
+ return true;
25
+ return cms.titleOf({ collection: targetCollection, id: d.id }).toLowerCase().includes(query.toLowerCase());
26
+ });
27
+ const isSelected = (id) => selected.some((r) => r.id === id);
28
+ function toggle(id) {
29
+ const ref = { collection: targetCollection, id };
30
+ if (cardinality === 'one') {
31
+ setSelected([ref]);
32
+ onChange([ref]);
33
+ onOpenChange(false);
34
+ return;
35
+ }
36
+ setSelected((prev) => (isSelected(id) ? prev.filter((r) => r.id !== id) : [...prev, ref]));
37
+ }
38
+ return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: "max-w-md", children: [_jsxs(DialogHeader, { children: [_jsxs(DialogTitle, { children: ["Pick ", cardinality === 'many' ? 'related' : 'a related', " document"] }), _jsxs(DialogDescription, { children: ["From ", _jsx(Code, { tone: "muted", children: targetCollection }), cardinality === 'many' ? ' · select multiple' : ''] })] }), _jsxs("div", { className: "relative", children: [_jsx(Search, { className: "pointer-events-none absolute left-2.5 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground" }), _jsx(Input, { autoFocus: true, value: query, onChange: (e) => setQuery(e.target.value), placeholder: "Search\u2026", className: "pl-8" })] }), _jsx("div", { className: "max-h-72 overflow-auto", children: candidates.length === 0 ? (_jsxs(Text, { size: "sm", tone: "muted", className: "p-3", children: ["No documents in ", targetCollection, "."] })) : (candidates.map((doc) => {
39
+ const title = cms.titleOf({ collection: targetCollection, id: doc.id });
40
+ const sel = isSelected(doc.id);
41
+ return (_jsxs("button", { type: "button", onClick: () => toggle(doc.id), className: cn('flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm transition-colors hover:bg-muted', sel && 'bg-accent text-accent-foreground'), children: [_jsx("span", { className: "min-w-0 flex-1 truncate font-medium", children: title }), _jsx(Code, { tone: "muted", children: doc.id }), sel ? _jsx(Check, { className: "size-4 text-primary" }) : null] }, doc.id));
42
+ })) }), cardinality === 'many' ? (_jsx(DialogFooter, { children: _jsxs(Row, { gap: "2", className: "w-full", children: [_jsxs(Badge, { variant: "outline", children: [selected.length, " selected"] }), _jsx(Spacer, {}), _jsx(Button, { variant: "ghost", onClick: () => onOpenChange(false), children: "Cancel" }), _jsx(Button, { onClick: () => {
43
+ onChange(selected);
44
+ onOpenChange(false);
45
+ }, children: "Apply" })] }) })) : null] }) }));
46
+ }
47
+ //# sourceMappingURL=relation-picker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relation-picker.js","sourceRoot":"","sources":["../../../src/components/cms/relation-picker.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import type { RefObject } from 'react';
2
+ import type { CmsDocument, CollectionDef } from '@elytracms/cms-core';
3
+ import type { AdvanceDirection, CellCoord } from './cell-edit';
4
+ /**
5
+ * Table-level cell-edit controller (EC-168). Owns the state machine the cells
6
+ * render from:
7
+ *
8
+ * idle → editing (click/Enter) → committing (Enter/Tab/blur) → idle
9
+ * ↘ cancelled (Esc, no operation) ↘ rejected (rollback + cell error)
10
+ *
11
+ * Exactly one cell edits at a time; commits go through
12
+ * `cms.commitFieldEdit` (one operations command each); rejections park a
13
+ * per-cell error that the cell renders inline until the cell is edited again.
14
+ */
15
+ export interface CellEditController {
16
+ /** Ref for the table container (focus restoration after commits/cancels). */
17
+ containerRef: RefObject<HTMLDivElement | null>;
18
+ /** Key of the cell currently editing, or null. */
19
+ activeKey: string | null;
20
+ /** Key of the cell with a commit in flight, or null. */
21
+ busyKey: string | null;
22
+ errorOf(key: string): string | null;
23
+ start(coord: CellCoord): void;
24
+ cancel(coord: CellCoord): void;
25
+ commit(coord: CellCoord, value: unknown, advance: AdvanceDirection | null): void;
26
+ }
27
+ export declare function useCellEdit({ collection, docs, editableFields, }: {
28
+ collection: CollectionDef;
29
+ /** Documents in rendered (sorted) row order. */
30
+ docs: readonly CmsDocument[];
31
+ /** Editable column field names in rendered order. */
32
+ editableFields: readonly string[];
33
+ }): CellEditController;
@@ -0,0 +1,125 @@
1
+ import { useCallback, useRef, useState } from 'react';
2
+ import { resolveField } from '@elytracms/cms-core';
3
+ import { cellErrorMessage, cellKey, nextEditableCell } from './cell-edit';
4
+ import { useCms } from './cms-store';
5
+ export function useCellEdit({ collection, docs, editableFields, }) {
6
+ const cms = useCms();
7
+ const [activeKey, setActiveKey] = useState(null);
8
+ const [busyKey, setBusyKey] = useState(null);
9
+ const [errors, setErrors] = useState({});
10
+ const containerRef = useRef(null);
11
+ // Snapshots for async commit completion (row order may re-sort mid-flight).
12
+ const activeRef = useRef(activeKey);
13
+ activeRef.current = activeKey;
14
+ const docsRef = useRef(docs);
15
+ docsRef.current = docs;
16
+ const fieldsRef = useRef(editableFields);
17
+ fieldsRef.current = editableFields;
18
+ const clearError = useCallback((key) => {
19
+ setErrors((prev) => {
20
+ if (!(key in prev))
21
+ return prev;
22
+ const next = { ...prev };
23
+ delete next[key];
24
+ return next;
25
+ });
26
+ }, []);
27
+ const focusCell = useCallback((key) => {
28
+ // After state settles: return focus to the cell so Enter re-edits and the
29
+ // keyboard flow continues where the user left off.
30
+ requestAnimationFrame(() => {
31
+ containerRef.current
32
+ ?.querySelector(`[data-cell-key="${CSS.escape(key)}"]`)
33
+ ?.focus();
34
+ });
35
+ }, []);
36
+ const start = useCallback((coord) => {
37
+ const key = cellKey(coord);
38
+ clearError(key);
39
+ setActiveKey(key);
40
+ }, [clearError]);
41
+ const cancel = useCallback((coord) => {
42
+ const key = cellKey(coord);
43
+ if (activeRef.current !== key)
44
+ return;
45
+ setActiveKey(null);
46
+ focusCell(key);
47
+ }, [focusCell]);
48
+ /** Close the editor and move on (commit settled or value unchanged). */
49
+ const settle = useCallback((coord, next) => {
50
+ const key = cellKey(coord);
51
+ // The user may have clicked into another cell while the commit ran —
52
+ // never clobber their new edit session.
53
+ if (activeRef.current !== key)
54
+ return;
55
+ if (next) {
56
+ clearError(cellKey(next));
57
+ setActiveKey(cellKey(next));
58
+ }
59
+ else {
60
+ setActiveKey(null);
61
+ focusCell(key);
62
+ }
63
+ }, [clearError, focusCell]);
64
+ const commit = useCallback((coord, value, advance) => {
65
+ const key = cellKey(coord);
66
+ const doc = docsRef.current.find((d) => d.id === coord.docId);
67
+ const field = collection.fields.find((f) => f.name === coord.field);
68
+ if (!doc || !field) {
69
+ settle(coord, null);
70
+ return;
71
+ }
72
+ // The advance target is computed against the row order at commit time —
73
+ // a re-sort caused by the edit must not teleport the cursor.
74
+ const next = advance
75
+ ? nextEditableCell(docsRef.current.map((d) => d.id), fieldsRef.current, coord, advance)
76
+ : null;
77
+ // Same value as displayed → close (and advance) without any operation.
78
+ // Notably: re-committing an unchanged fallback-shown value dispatches
79
+ // nothing — a localized variant is only created by an actual edit.
80
+ const locale = cms.activeLocale;
81
+ const original = resolveField(collection, doc, field.name, locale, cms.localeConfig).value;
82
+ if (sameCellValue(value, original)) {
83
+ settle(coord, next);
84
+ return;
85
+ }
86
+ setBusyKey(key);
87
+ void cms
88
+ .commitFieldEdit({ collection, doc, field, locale, value })
89
+ .then((outcome) => {
90
+ if (outcome.ok) {
91
+ clearError(key);
92
+ settle(coord, next);
93
+ return;
94
+ }
95
+ // Rejected: the session already rolled back — park the error on the
96
+ // cell (never a toast) and return focus there.
97
+ setErrors((prev) => ({ ...prev, [key]: cellErrorMessage(outcome.error) }));
98
+ settle(coord, null);
99
+ })
100
+ .finally(() => {
101
+ setBusyKey((prev) => (prev === key ? null : prev));
102
+ });
103
+ }, [cms, collection, clearError, settle]);
104
+ return {
105
+ containerRef,
106
+ activeKey,
107
+ busyKey,
108
+ errorOf: (key) => errors[key] ?? null,
109
+ start,
110
+ cancel,
111
+ commit,
112
+ };
113
+ }
114
+ /** Structural equality good enough for cell values (scalars, refs, id arrays). */
115
+ function sameCellValue(a, b) {
116
+ if (a === undefined && b === undefined)
117
+ return true;
118
+ try {
119
+ return JSON.stringify(a) === JSON.stringify(b);
120
+ }
121
+ catch {
122
+ return false;
123
+ }
124
+ }
125
+ //# sourceMappingURL=use-cell-edit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-cell-edit.js","sourceRoot":"","sources":["../../../src/components/cms/use-cell-edit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { CmsDocument } from '@elytracms/cms-core';
2
+ /**
3
+ * Does a recorded snapshot equal the working draft, by VALUE (EC-224)? Decides
4
+ * whether the Versions pane shows "unpublished changes".
5
+ *
6
+ * The compare MUST be canonical (key-order-insensitive): a recorded snapshot is
7
+ * round-tripped through `documentSchema` on save (which reorders object keys to
8
+ * the schema's declaration order), while the live draft is assembled by the
9
+ * editor's spread-mutations (keys in mutation order). A plain `JSON.stringify`
10
+ * equality is order-sensitive, so it would report a just-published, byte-equal
11
+ * document as still having changes — pinning the Publish affordance on forever.
12
+ */
13
+ export declare function snapshotMatchesDraft(snapshot: CmsDocument, draft: CmsDocument): boolean;
14
+ /** Format a version's stored timestamp; fall back to the raw value if unparseable. */
15
+ export declare function formatVersionTimestamp(value: string): string;
@@ -0,0 +1,23 @@
1
+ import { stableStringify } from '@elytracms/content';
2
+ /**
3
+ * Does a recorded snapshot equal the working draft, by VALUE (EC-224)? Decides
4
+ * whether the Versions pane shows "unpublished changes".
5
+ *
6
+ * The compare MUST be canonical (key-order-insensitive): a recorded snapshot is
7
+ * round-tripped through `documentSchema` on save (which reorders object keys to
8
+ * the schema's declaration order), while the live draft is assembled by the
9
+ * editor's spread-mutations (keys in mutation order). A plain `JSON.stringify`
10
+ * equality is order-sensitive, so it would report a just-published, byte-equal
11
+ * document as still having changes — pinning the Publish affordance on forever.
12
+ */
13
+ export function snapshotMatchesDraft(snapshot, draft) {
14
+ return stableStringify(snapshot) === stableStringify(draft);
15
+ }
16
+ /** Format a version's stored timestamp; fall back to the raw value if unparseable. */
17
+ export function formatVersionTimestamp(value) {
18
+ const ms = Date.parse(value);
19
+ if (Number.isNaN(ms))
20
+ return value;
21
+ return new Date(ms).toLocaleString();
22
+ }
23
+ //# sourceMappingURL=versions-model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"versions-model.js","sourceRoot":"","sources":["../../../src/components/cms/versions-model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAGpD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,oBAAoB,CAAC,QAAqB,EAAE,KAAkB;IAC5E,OAAO,eAAe,CAAC,QAAQ,CAAC,KAAK,eAAe,CAAC,KAAK,CAAC,CAAA;AAC7D,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,sBAAsB,CAAC,KAAa;IAClD,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IAC5B,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAAE,OAAO,KAAK,CAAA;IAClC,OAAO,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,cAAc,EAAE,CAAA;AACtC,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * EC-224 — the document-level **Versions** inspector pane. Re-homes the EC-180
3
+ * VersionsPanel at the document level (the Sanity model): the continuous draft
4
+ * on top with **Publish**, then the recorded version history (the live pin
5
+ * badged), each older version **restorable** into the draft.
6
+ *
7
+ * Publish routes through the same pointer op as the header control
8
+ * (`cms.publishDocument`); restore loads a recorded snapshot as the new working
9
+ * draft (the operation snapshots the current draft first, so a rollback is
10
+ * itself undoable) and the open editor adopts it via `replaceDraft`. Unpublish
11
+ * deliberately stays in the header — it routes through the EC-173
12
+ * reference-aware confirmation, which this pane does not duplicate.
13
+ */
14
+ export declare function VersionsPane(): import("react").JSX.Element;
@@ -0,0 +1,86 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useState } from 'react';
3
+ import { Eye, RotateCcw } from 'lucide-react';
4
+ import { Badge, Button, Code, Row, Spacer, Stack, Text } from '@elytracms/studio/ui';
5
+ import { useCms } from './cms-store';
6
+ import { useDocumentEditor } from './document-editor-context';
7
+ import { formatVersionTimestamp, snapshotMatchesDraft } from './versions-model';
8
+ /**
9
+ * EC-224 — the document-level **Versions** inspector pane. Re-homes the EC-180
10
+ * VersionsPanel at the document level (the Sanity model): the continuous draft
11
+ * on top with **Publish**, then the recorded version history (the live pin
12
+ * badged), each older version **restorable** into the draft.
13
+ *
14
+ * Publish routes through the same pointer op as the header control
15
+ * (`cms.publishDocument`); restore loads a recorded snapshot as the new working
16
+ * draft (the operation snapshots the current draft first, so a rollback is
17
+ * itself undoable) and the open editor adopts it via `replaceDraft`. Unpublish
18
+ * deliberately stays in the header — it routes through the EC-173
19
+ * reference-aware confirmation, which this pane does not duplicate.
20
+ */
21
+ export function VersionsPane() {
22
+ const cms = useCms();
23
+ const { docRef, draft, dirty, hasErrors, viewReadOnly, save, replaceDraft } = useDocumentEditor();
24
+ const [view, setView] = useState(null);
25
+ const [busy, setBusy] = useState(false);
26
+ const published = cms.isPublished(docRef);
27
+ const reload = useCallback(async () => {
28
+ // Flush any queued publish/save so the listed history is authoritative
29
+ // regardless of which surface (header or pane) triggered the change.
30
+ await cms.flushPersistence();
31
+ setView(await cms.loadDocumentVersions(docRef));
32
+ }, [cms, docRef]);
33
+ useEffect(() => {
34
+ void reload();
35
+ // Re-load when publish-ness flips from anywhere (e.g. the header control).
36
+ }, [reload, published]);
37
+ const liveSnapshot = view?.publishedVersion !== undefined
38
+ ? view.versions.find((v) => v.version === view.publishedVersion)?.snapshot
39
+ : undefined;
40
+ // Value-equality (key-order-insensitive) so a just-published, unchanged doc
41
+ // doesn't read as "unpublished changes" — see snapshotMatchesDraft.
42
+ const liveMatchesDraft = liveSnapshot !== undefined && snapshotMatchesDraft(liveSnapshot, draft);
43
+ const canPublish = !liveMatchesDraft;
44
+ const handlePublish = useCallback(async () => {
45
+ setBusy(true);
46
+ try {
47
+ // Publish snapshots the SAVED draft — capture any unsaved edits first so
48
+ // the published version is exactly what the editor shows. Await the
49
+ // publish (it flushes + reconciles the pin, EC-225) before re-reading the
50
+ // version list so the new version shows.
51
+ if (dirty)
52
+ save();
53
+ await cms.publishDocument(docRef);
54
+ await reload();
55
+ }
56
+ finally {
57
+ setBusy(false);
58
+ }
59
+ }, [cms, docRef, dirty, save, reload]);
60
+ const handleRestore = useCallback(async (version) => {
61
+ setBusy(true);
62
+ try {
63
+ // Capture any unsaved buffer edits FIRST so the operation's pre-restore
64
+ // snapshot records them — otherwise they'd be lost and the rollback
65
+ // wouldn't be undoable (restore snapshots the persisted draft).
66
+ if (dirty)
67
+ save();
68
+ const restored = await cms.restoreDocumentVersion(docRef, version);
69
+ if (restored)
70
+ replaceDraft(restored);
71
+ await reload();
72
+ }
73
+ finally {
74
+ setBusy(false);
75
+ }
76
+ }, [cms, docRef, dirty, save, replaceDraft, reload]);
77
+ return (_jsxs(Stack, { gap: "3", className: "p-3", children: [canPublish ? (_jsxs(Row, { gap: "2", align: "center", className: "rounded-md border border-primary/40 bg-primary/5 px-2.5 py-2", children: [_jsxs(Stack, { gap: "none", className: "min-w-0", children: [_jsx(Text, { size: "sm", weight: "medium", children: "Draft" }), _jsx(Text, { size: "xs", tone: "muted", children: published ? 'Unpublished changes' : 'Not published yet' })] }), _jsx(Spacer, {}), _jsxs(Button, { size: "sm", onClick: handlePublish, disabled: busy || hasErrors || viewReadOnly, title: viewReadOnly
78
+ ? 'Switch to Draft to publish'
79
+ : hasErrors
80
+ ? 'Fix the document’s validation issues to publish'
81
+ : undefined, children: [_jsx(Eye, {}), " Publish"] })] })) : (_jsx(Text, { size: "xs", tone: "muted", className: "px-0.5", children: "The live version is up to date \u2014 nothing to publish." })), _jsx(Stack, { gap: "1", children: view === null ? (_jsx(Text, { size: "xs", tone: "muted", className: "px-0.5", children: "Loading\u2026" })) : view.versions.length === 0 ? (_jsx(Text, { size: "xs", tone: "muted", className: "px-0.5", children: "No published versions yet." })) : (view.versions.map((entry) => {
82
+ const isLive = entry.version === view.publishedVersion;
83
+ return (_jsxs(Row, { gap: "2", align: "center", className: "rounded-md border border-border/60 px-2.5 py-1.5", children: [_jsxs(Code, { tone: isLive ? 'primary' : 'muted', children: ["v", entry.version] }), isLive ? _jsx(Badge, { variant: "success", children: "Published" }) : null, _jsx(Text, { size: "xs", tone: "subtle", mono: true, className: "truncate", children: formatVersionTimestamp(entry.createdAt) }), _jsx(Spacer, {}), isLive ? null : (_jsxs(Button, { size: "sm", variant: "outline", onClick: () => void handleRestore(entry.version), disabled: busy || viewReadOnly, title: viewReadOnly ? 'Switch to Draft to restore' : undefined, children: [_jsx(RotateCcw, {}), " Restore"] }))] }, entry.version));
84
+ })) })] }));
85
+ }
86
+ //# sourceMappingURL=versions-pane.js.map