canopycms 0.0.68-int.98 → 0.1.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 (688) hide show
  1. package/CHANGELOG.md +2131 -0
  2. package/README.md +47 -63
  3. package/dist/ai/generate.d.ts +5 -0
  4. package/dist/ai/generate.js +244 -115
  5. package/dist/ai/index.d.ts +1 -1
  6. package/dist/ai/json-to-markdown.d.ts +21 -1
  7. package/dist/ai/json-to-markdown.js +120 -57
  8. package/dist/ai/references.d.ts +72 -0
  9. package/dist/ai/references.js +223 -0
  10. package/dist/ai/resolve-branch.js +9 -2
  11. package/dist/ai/to-plain-text.d.ts +17 -8
  12. package/dist/ai/to-plain-text.js +18 -15
  13. package/dist/ai/types.d.ts +84 -3
  14. package/dist/api/admin-branch-health.d.ts +24 -1
  15. package/dist/api/admin-branch-health.js +52 -20
  16. package/dist/api/admin.d.ts +23 -5
  17. package/dist/api/admin.js +36 -1
  18. package/dist/api/assets.js +88 -78
  19. package/dist/api/branch-create-window.d.ts +12 -0
  20. package/dist/api/branch-create-window.js +13 -0
  21. package/dist/api/branch-merge.d.ts +1 -1
  22. package/dist/api/branch-merge.js +1 -1
  23. package/dist/api/branch-review.d.ts +3 -3
  24. package/dist/api/branch-review.js +16 -7
  25. package/dist/api/branch-status.d.ts +16 -6
  26. package/dist/api/branch-status.js +57 -12
  27. package/dist/api/branch-withdraw.d.ts +2 -2
  28. package/dist/api/branch-withdraw.js +8 -3
  29. package/dist/api/branch.d.ts +25 -12
  30. package/dist/api/branch.js +164 -103
  31. package/dist/api/client.d.ts +78 -58
  32. package/dist/api/client.js +150 -117
  33. package/dist/api/comments.d.ts +12 -3
  34. package/dist/api/comments.js +118 -9
  35. package/dist/api/content.d.ts +9 -9
  36. package/dist/api/content.js +131 -22
  37. package/dist/api/entries-constants.d.ts +14 -3
  38. package/dist/api/entries-constants.js +14 -3
  39. package/dist/api/entries.d.ts +40 -2
  40. package/dist/api/entries.js +102 -6
  41. package/dist/api/github-sync.d.ts +19 -0
  42. package/dist/api/github-sync.js +50 -3
  43. package/dist/api/groups.d.ts +4 -4
  44. package/dist/api/groups.js +2 -1
  45. package/dist/api/guards.js +23 -3
  46. package/dist/api/index.d.ts +3 -1
  47. package/dist/api/index.js +1 -0
  48. package/dist/api/permissions.d.ts +21 -2
  49. package/dist/api/permissions.js +50 -3
  50. package/dist/api/request-deadline.d.ts +59 -0
  51. package/dist/api/request-deadline.js +73 -0
  52. package/dist/api/resolve-references.js +8 -7
  53. package/dist/api/route-builder.d.ts +14 -0
  54. package/dist/api/route-builder.js +14 -1
  55. package/dist/api/schema.d.ts +11 -9
  56. package/dist/api/schema.js +2 -0
  57. package/dist/api/settings-helpers.d.ts +5 -1
  58. package/dist/api/settings-helpers.js +10 -2
  59. package/dist/api/types.d.ts +18 -0
  60. package/dist/api/users-constants.d.ts +6 -0
  61. package/dist/api/users-constants.js +6 -0
  62. package/dist/assets/asset-url.d.ts +28 -16
  63. package/dist/assets/asset-url.js +51 -25
  64. package/dist/assets/finalize.js +3 -0
  65. package/dist/assets/index.d.ts +1 -1
  66. package/dist/assets/materialize.d.ts +153 -0
  67. package/dist/assets/materialize.js +402 -0
  68. package/dist/assets/store-local.d.ts +19 -5
  69. package/dist/assets/store-local.js +69 -10
  70. package/dist/assets/store-s3.d.ts +38 -7
  71. package/dist/assets/store-s3.js +128 -22
  72. package/dist/assets/transform-directives.d.ts +52 -13
  73. package/dist/assets/transform-directives.js +87 -27
  74. package/dist/assets/transform.d.ts +3 -3
  75. package/dist/assets/transform.js +13 -8
  76. package/dist/assets/types.d.ts +31 -4
  77. package/dist/auth/cache.d.ts +1 -1
  78. package/dist/auth/cache.js +1 -1
  79. package/dist/auth/caching-auth-plugin.d.ts +2 -0
  80. package/dist/auth/caching-auth-plugin.js +12 -2
  81. package/dist/auth/file-based-auth-cache.d.ts +8 -0
  82. package/dist/auth/file-based-auth-cache.js +18 -8
  83. package/dist/auth/person-name.d.ts +5 -0
  84. package/dist/auth/person-name.js +8 -0
  85. package/dist/auth/plugin.d.ts +10 -1
  86. package/dist/auth/types.d.ts +2 -0
  87. package/dist/auth/user-metadata-lookup.d.ts +21 -0
  88. package/dist/auth/user-metadata-lookup.js +116 -0
  89. package/dist/authorization/branch.d.ts +1 -1
  90. package/dist/authorization/branch.js +12 -13
  91. package/dist/authorization/groups/schema.d.ts +4 -4
  92. package/dist/authorization/helpers.d.ts +8 -0
  93. package/dist/authorization/helpers.js +8 -0
  94. package/dist/authorization/index.d.ts +1 -1
  95. package/dist/authorization/index.js +1 -1
  96. package/dist/authorization/protected-branch.d.ts +5 -4
  97. package/dist/authorization/protected-branch.js +7 -5
  98. package/dist/branch-health.d.ts +35 -8
  99. package/dist/branch-health.js +54 -18
  100. package/dist/branch-metadata-error.d.ts +27 -0
  101. package/dist/branch-metadata-error.js +23 -0
  102. package/dist/branch-metadata-file.d.ts +205 -24
  103. package/dist/branch-metadata-file.js +126 -25
  104. package/dist/branch-metadata.d.ts +45 -6
  105. package/dist/branch-metadata.js +142 -50
  106. package/dist/branch-provisioning.d.ts +167 -0
  107. package/dist/branch-provisioning.js +501 -0
  108. package/dist/branch-registry.d.ts +8 -0
  109. package/dist/branch-registry.js +61 -9
  110. package/dist/branch-schema-cache.d.ts +29 -12
  111. package/dist/branch-schema-cache.js +64 -21
  112. package/dist/branch-sparse.d.ts +23 -0
  113. package/dist/branch-sparse.js +118 -0
  114. package/dist/branch-workspace.d.ts +42 -3
  115. package/dist/branch-workspace.js +239 -100
  116. package/dist/build/asset-refs.d.ts +94 -0
  117. package/dist/build/asset-refs.js +267 -0
  118. package/dist/build/generate-ai-content.js +5 -0
  119. package/dist/build/inline-flight.d.ts +37 -0
  120. package/dist/build/inline-flight.js +142 -0
  121. package/dist/cli/asset-refs.d.ts +52 -0
  122. package/dist/cli/asset-refs.js +194 -0
  123. package/dist/cli/cli.d.ts +15 -1
  124. package/dist/cli/cli.js +8543 -3193
  125. package/dist/cli/configured-asset-store.d.ts +12 -0
  126. package/dist/cli/configured-asset-store.js +46 -0
  127. package/dist/cli/generate-ai-content.js +4244 -1072
  128. package/dist/cli/init.js +217 -126
  129. package/dist/cli/project-detect.d.ts +2 -0
  130. package/dist/cli/project-detect.js +2 -0
  131. package/dist/cli/template-files/Dockerfile.cms.template +13 -5
  132. package/dist/cli/template-files/cms-stack.ts.template +16 -13
  133. package/dist/client.d.ts +1 -2
  134. package/dist/client.js +1 -2
  135. package/dist/comment-store.d.ts +25 -0
  136. package/dist/comment-store.js +43 -8
  137. package/dist/config/flatten.js +2 -0
  138. package/dist/config/helpers.js +2 -2
  139. package/dist/config/index.d.ts +1 -1
  140. package/dist/config/schemas/config.d.ts +12 -29
  141. package/dist/config/schemas/config.js +9 -12
  142. package/dist/config/schemas/field.d.ts +3 -0
  143. package/dist/config/schemas/field.js +58 -4
  144. package/dist/config/schemas/media.d.ts +4 -13
  145. package/dist/config/schemas/media.js +5 -8
  146. package/dist/config/schemas/url.d.ts +2 -20
  147. package/dist/config/schemas/url.js +2 -25
  148. package/dist/config/types.d.ts +116 -22
  149. package/dist/config/types.js +3 -9
  150. package/dist/config/validation.d.ts +25 -4
  151. package/dist/config/validation.js +116 -3
  152. package/dist/content-id-index.js +2 -2
  153. package/dist/content-index-generation.d.ts +1 -1
  154. package/dist/content-index-generation.js +1 -1
  155. package/dist/content-listing.d.ts +10 -1
  156. package/dist/content-listing.js +22 -5
  157. package/dist/content-reader.d.ts +9 -0
  158. package/dist/content-reader.js +16 -11
  159. package/dist/content-store.d.ts +75 -12
  160. package/dist/content-store.js +249 -86
  161. package/dist/content-tree.js +2 -2
  162. package/dist/context.js +5 -2
  163. package/dist/dangling-reference-log.d.ts +17 -0
  164. package/dist/dangling-reference-log.js +29 -0
  165. package/dist/dev-content-watcher.d.ts +1 -1
  166. package/dist/dev-content-watcher.js +1 -1
  167. package/dist/editor/BranchManager.d.ts +23 -7
  168. package/dist/editor/BranchManager.js +119 -54
  169. package/dist/editor/CanopyEditor.d.ts +1 -1
  170. package/dist/editor/CanopyEditor.js +1 -2
  171. package/dist/editor/CommentsPanel.d.ts +14 -0
  172. package/dist/editor/CommentsPanel.js +68 -43
  173. package/dist/editor/Editor.d.ts +11 -5
  174. package/dist/editor/Editor.js +891 -218
  175. package/dist/editor/EditorAuthGate.d.ts +7 -1
  176. package/dist/editor/EditorAuthGate.js +41 -9
  177. package/dist/editor/EntryNavigator.d.ts +22 -0
  178. package/dist/editor/EntryNavigator.js +353 -105
  179. package/dist/editor/FormHeader.d.ts +25 -0
  180. package/dist/editor/FormHeader.js +82 -0
  181. package/dist/editor/FormRenderer.d.ts +27 -3
  182. package/dist/editor/FormRenderer.js +171 -76
  183. package/dist/editor/PreviewFrame.d.ts +40 -0
  184. package/dist/editor/PreviewFrame.js +215 -0
  185. package/dist/editor/PreviewPane.d.ts +47 -0
  186. package/dist/editor/PreviewPane.js +147 -0
  187. package/dist/editor/PreviewToolbarTools.d.ts +22 -0
  188. package/dist/editor/PreviewToolbarTools.js +73 -0
  189. package/dist/editor/admin/SystemHealthPanel.d.ts +2 -1
  190. package/dist/editor/admin/SystemHealthPanel.js +163 -33
  191. package/dist/editor/admin/useSystemHealth.d.ts +18 -0
  192. package/dist/editor/admin/useSystemHealth.js +70 -1
  193. package/dist/editor/branch-status.d.ts +17 -0
  194. package/dist/editor/branch-status.js +29 -0
  195. package/dist/editor/canopy-path.d.ts +9 -6
  196. package/dist/editor/canopy-path.js +8 -11
  197. package/dist/editor/client-reference-resolver.d.ts +43 -16
  198. package/dist/editor/client-reference-resolver.js +155 -64
  199. package/dist/editor/comments/BranchComments.d.ts +1 -1
  200. package/dist/editor/comments/BranchComments.js +2 -2
  201. package/dist/editor/comments/CloseRefusedNotice.d.ts +4 -0
  202. package/dist/editor/comments/CloseRefusedNotice.js +7 -0
  203. package/dist/editor/comments/CommentThreadsPopover.d.ts +47 -0
  204. package/dist/editor/comments/CommentThreadsPopover.js +274 -0
  205. package/dist/editor/comments/CommentWriteAlert.d.ts +11 -0
  206. package/dist/editor/comments/CommentWriteAlert.js +13 -0
  207. package/dist/editor/comments/EntryComments.d.ts +10 -4
  208. package/dist/editor/comments/EntryComments.js +14 -17
  209. package/dist/editor/comments/FieldWrapper.d.ts +18 -4
  210. package/dist/editor/comments/FieldWrapper.js +62 -28
  211. package/dist/editor/comments/InlineCommentThread.d.ts +9 -2
  212. package/dist/editor/comments/InlineCommentThread.js +11 -47
  213. package/dist/editor/comments/ThreadCarousel.d.ts +1 -1
  214. package/dist/editor/comments/ThreadCarousel.js +18 -21
  215. package/dist/editor/comments/ThreadReplyControls.d.ts +28 -0
  216. package/dist/editor/comments/ThreadReplyControls.js +92 -0
  217. package/dist/editor/comments/field-comment-context.d.ts +14 -0
  218. package/dist/editor/comments/field-comment-context.js +14 -0
  219. package/dist/editor/comments/form-comments.d.ts +48 -0
  220. package/dist/editor/comments/form-comments.js +178 -0
  221. package/dist/editor/comments/item-anchor-copy.d.ts +6 -0
  222. package/dist/editor/comments/item-anchor-copy.js +6 -0
  223. package/dist/editor/comments/move-focus-if-unmoved.d.ts +6 -0
  224. package/dist/editor/comments/move-focus-if-unmoved.js +11 -0
  225. package/dist/editor/comments/popover-placement.d.ts +18 -0
  226. package/dist/editor/comments/popover-placement.js +58 -0
  227. package/dist/editor/comments/use-tracked-writes.d.ts +16 -0
  228. package/dist/editor/comments/use-tracked-writes.js +53 -0
  229. package/dist/editor/components/BranchAccessList.d.ts +15 -0
  230. package/dist/editor/components/BranchAccessList.js +52 -0
  231. package/dist/editor/components/BranchLockBanner.d.ts +22 -0
  232. package/dist/editor/components/BranchLockBanner.js +39 -0
  233. package/dist/editor/components/BranchPill.d.ts +32 -0
  234. package/dist/editor/components/BranchPill.js +33 -0
  235. package/dist/editor/components/BranchesDrawer.d.ts +11 -0
  236. package/dist/editor/components/BranchesDrawer.js +5 -0
  237. package/dist/editor/components/ConfirmDeleteModal.d.ts +6 -1
  238. package/dist/editor/components/ConfirmDeleteModal.js +3 -2
  239. package/dist/editor/components/DestructiveMenuItem.d.ts +7 -0
  240. package/dist/editor/components/DestructiveMenuItem.js +8 -0
  241. package/dist/editor/components/EditorCrashScreen.d.ts +17 -0
  242. package/dist/editor/components/EditorCrashScreen.js +22 -0
  243. package/dist/editor/components/EditorErrorBoundary.d.ts +38 -0
  244. package/dist/editor/components/EditorErrorBoundary.js +40 -0
  245. package/dist/editor/components/EditorHeader.d.ts +56 -106
  246. package/dist/editor/components/EditorHeader.js +130 -131
  247. package/dist/editor/components/EditorRail.d.ts +49 -0
  248. package/dist/editor/components/EditorRail.js +65 -0
  249. package/dist/editor/components/EntryBreadcrumb.d.ts +33 -0
  250. package/dist/editor/components/EntryBreadcrumb.js +56 -0
  251. package/dist/editor/components/EntryCreateModal.d.ts +12 -7
  252. package/dist/editor/components/EntryCreateModal.js +51 -57
  253. package/dist/editor/components/NoEditPermissionNotice.d.ts +6 -5
  254. package/dist/editor/components/NoEditPermissionNotice.js +5 -4
  255. package/dist/editor/components/QuickOpenPalette.d.ts +22 -0
  256. package/dist/editor/components/QuickOpenPalette.js +66 -0
  257. package/dist/editor/components/ReadOnlyDraftNotice.d.ts +11 -0
  258. package/dist/editor/components/ReadOnlyDraftNotice.js +12 -0
  259. package/dist/editor/components/ReasonedMenuItem.d.ts +15 -0
  260. package/dist/editor/components/ReasonedMenuItem.js +15 -0
  261. package/dist/editor/components/ReferencedByList.d.ts +11 -0
  262. package/dist/editor/components/ReferencedByList.js +28 -0
  263. package/dist/editor/components/RelativeTime.d.ts +10 -0
  264. package/dist/editor/components/RelativeTime.js +10 -0
  265. package/dist/editor/components/RenameEntryModal.d.ts +9 -1
  266. package/dist/editor/components/RenameEntryModal.js +19 -31
  267. package/dist/editor/components/RetryToastMessage.d.ts +9 -0
  268. package/dist/editor/components/RetryToastMessage.js +6 -0
  269. package/dist/editor/components/SaveAllResult.d.ts +25 -0
  270. package/dist/editor/components/SaveAllResult.js +86 -0
  271. package/dist/editor/components/SaveSplitButton.d.ts +30 -0
  272. package/dist/editor/components/SaveSplitButton.js +108 -0
  273. package/dist/editor/components/StagedChangesDrawer.d.ts +39 -0
  274. package/dist/editor/components/StagedChangesDrawer.js +92 -0
  275. package/dist/editor/components/UnavailableEntryNotice.d.ts +6 -0
  276. package/dist/editor/components/UnavailableEntryNotice.js +9 -0
  277. package/dist/editor/components/UnavailableTypeMessage.d.ts +6 -0
  278. package/dist/editor/components/UnavailableTypeMessage.js +9 -0
  279. package/dist/editor/components/UndoToastMessage.d.ts +18 -0
  280. package/dist/editor/components/UndoToastMessage.js +10 -0
  281. package/dist/editor/components/UserBadge.d.ts +2 -5
  282. package/dist/editor/components/UserBadge.js +62 -33
  283. package/dist/editor/components/ValidationSummary.d.ts +14 -0
  284. package/dist/editor/components/ValidationSummary.js +24 -0
  285. package/dist/editor/components/index.d.ts +2 -2
  286. package/dist/editor/components/index.js +2 -2
  287. package/dist/editor/context/ApiClientContext.d.ts +8 -2
  288. package/dist/editor/context/ApiClientContext.js +19 -8
  289. package/dist/editor/context/AssetContext.d.ts +13 -35
  290. package/dist/editor/context/AssetContext.js +12 -31
  291. package/dist/editor/context/EditorStateContext.d.ts +4 -4
  292. package/dist/editor/context/EditorStateContext.js +4 -4
  293. package/dist/editor/context/SWRProvider.d.ts +3 -3
  294. package/dist/editor/context/SiteMdxAllowContext.d.ts +4 -0
  295. package/dist/editor/context/SiteMdxAllowContext.js +7 -0
  296. package/dist/editor/context/index.d.ts +2 -1
  297. package/dist/editor/context/index.js +2 -1
  298. package/dist/editor/contrast.d.ts +19 -0
  299. package/dist/editor/contrast.js +41 -0
  300. package/dist/editor/copy.d.ts +18 -0
  301. package/dist/editor/copy.js +18 -0
  302. package/dist/editor/editor-config.js +16 -0
  303. package/dist/editor/editor-utils.d.ts +34 -8
  304. package/dist/editor/editor-utils.js +42 -20
  305. package/dist/editor/entry-search.d.ts +20 -0
  306. package/dist/editor/entry-search.js +34 -0
  307. package/dist/editor/field-breadcrumb.d.ts +12 -0
  308. package/dist/editor/field-breadcrumb.js +85 -0
  309. package/dist/editor/field-props.d.ts +86 -0
  310. package/dist/editor/field-props.js +27 -0
  311. package/dist/editor/field-target.d.ts +30 -0
  312. package/dist/editor/field-target.js +77 -0
  313. package/dist/editor/fields/BlockField.d.ts +12 -0
  314. package/dist/editor/fields/BlockField.js +89 -73
  315. package/dist/editor/fields/CodeField.d.ts +2 -0
  316. package/dist/editor/fields/CodeField.js +6 -2
  317. package/dist/editor/fields/DateTimeField.d.ts +4 -29
  318. package/dist/editor/fields/DateTimeField.js +79 -41
  319. package/dist/editor/fields/ExpandAllButton.d.ts +6 -0
  320. package/dist/editor/fields/ExpandAllButton.js +4 -0
  321. package/dist/editor/fields/FieldCrashFallback.d.ts +17 -0
  322. package/dist/editor/fields/FieldCrashFallback.js +30 -0
  323. package/dist/editor/fields/FieldLabel.d.ts +37 -0
  324. package/dist/editor/fields/FieldLabel.js +19 -0
  325. package/dist/editor/fields/ImageField.d.ts +4 -0
  326. package/dist/editor/fields/ImageField.js +29 -14
  327. package/dist/editor/fields/InlineGroupField.js +4 -3
  328. package/dist/editor/fields/ItemList.d.ts +42 -0
  329. package/dist/editor/fields/ItemList.js +130 -0
  330. package/dist/editor/fields/MarkdownField.d.ts +32 -0
  331. package/dist/editor/fields/MarkdownField.js +223 -46
  332. package/dist/editor/fields/MdxImageDialog.js +1 -1
  333. package/dist/editor/fields/NumberField.d.ts +2 -0
  334. package/dist/editor/fields/NumberField.js +8 -5
  335. package/dist/editor/fields/NumberListField.d.ts +2 -0
  336. package/dist/editor/fields/NumberListField.js +19 -16
  337. package/dist/editor/fields/ObjectField.d.ts +2 -7
  338. package/dist/editor/fields/ObjectField.js +15 -5
  339. package/dist/editor/fields/ObjectListField.d.ts +29 -0
  340. package/dist/editor/fields/ObjectListField.js +57 -0
  341. package/dist/editor/fields/ReferenceField.d.ts +2 -0
  342. package/dist/editor/fields/ReferenceField.js +34 -9
  343. package/dist/editor/fields/SelectField.d.ts +2 -0
  344. package/dist/editor/fields/SelectField.js +11 -2
  345. package/dist/editor/fields/StringListField.d.ts +4 -1
  346. package/dist/editor/fields/StringListField.js +22 -8
  347. package/dist/editor/fields/TextField.d.ts +2 -0
  348. package/dist/editor/fields/TextField.js +6 -2
  349. package/dist/editor/fields/ToggleField.d.ts +2 -0
  350. package/dist/editor/fields/ToggleField.js +8 -3
  351. package/dist/editor/fields/entry-link/InsertEntryLink.d.ts +1 -1
  352. package/dist/editor/fields/entry-link/InsertEntryLink.js +1 -1
  353. package/dist/editor/fields/form-expansion.d.ts +9 -0
  354. package/dist/editor/fields/form-expansion.js +2 -0
  355. package/dist/editor/fields/item-expansion.d.ts +15 -0
  356. package/dist/editor/fields/item-expansion.js +60 -0
  357. package/dist/editor/fields/list-item-keys.d.ts +8 -0
  358. package/dist/editor/fields/list-item-keys.js +50 -0
  359. package/dist/editor/fields/list-item-title.d.ts +20 -0
  360. package/dist/editor/fields/list-item-title.js +85 -0
  361. package/dist/editor/fields/markdown-export-options.d.ts +2 -0
  362. package/dist/editor/fields/markdown-export-options.js +8 -0
  363. package/dist/editor/fields/markdown-fidelity-visitors.d.ts +11 -0
  364. package/dist/editor/fields/markdown-fidelity-visitors.js +160 -0
  365. package/dist/editor/fields/mdx-jsx-support.d.ts +5 -1
  366. package/dist/editor/fields/mdx-jsx-support.js +157 -69
  367. package/dist/editor/fields/rich-text-failures.d.ts +5 -0
  368. package/dist/editor/fields/rich-text-failures.js +26 -0
  369. package/dist/editor/fields/toolbar-wrap.d.ts +7 -0
  370. package/dist/editor/fields/toolbar-wrap.js +35 -0
  371. package/dist/editor/form-outline.d.ts +13 -0
  372. package/dist/editor/form-outline.js +70 -0
  373. package/dist/editor/group-manager/GroupCard.d.ts +4 -1
  374. package/dist/editor/group-manager/GroupCard.js +12 -3
  375. package/dist/editor/group-manager/GroupForm.js +1 -1
  376. package/dist/editor/group-manager/InternalGroupsTab.d.ts +2 -1
  377. package/dist/editor/group-manager/InternalGroupsTab.js +4 -4
  378. package/dist/editor/group-manager/MemberList.d.ts +2 -1
  379. package/dist/editor/group-manager/MemberList.js +15 -4
  380. package/dist/editor/group-manager/hooks/useGroupState.d.ts +5 -0
  381. package/dist/editor/group-manager/hooks/useGroupState.js +30 -7
  382. package/dist/editor/group-manager/index.js +34 -5
  383. package/dist/editor/group-manager/types.d.ts +5 -2
  384. package/dist/editor/hooks/create-branch-request.d.ts +20 -0
  385. package/dist/editor/hooks/create-branch-request.js +54 -0
  386. package/dist/editor/hooks/save-all.d.ts +68 -0
  387. package/dist/editor/hooks/save-all.js +61 -0
  388. package/dist/editor/hooks/useBranchActions.d.ts +11 -1
  389. package/dist/editor/hooks/useBranchActions.js +42 -19
  390. package/dist/editor/hooks/useBranchManager.d.ts +21 -0
  391. package/dist/editor/hooks/useBranchManager.js +321 -125
  392. package/dist/editor/hooks/useBranchesData.d.ts +8 -4
  393. package/dist/editor/hooks/useBranchesData.js +9 -5
  394. package/dist/editor/hooks/useCommentSystem.d.ts +14 -2
  395. package/dist/editor/hooks/useCommentSystem.js +79 -55
  396. package/dist/editor/hooks/useCommentsData.d.ts +11 -7
  397. package/dist/editor/hooks/useCommentsData.js +20 -19
  398. package/dist/editor/hooks/useDraftManager.d.ts +77 -3
  399. package/dist/editor/hooks/useDraftManager.js +887 -94
  400. package/dist/editor/hooks/useEditorLayout.d.ts +53 -7
  401. package/dist/editor/hooks/useEditorLayout.js +98 -20
  402. package/dist/editor/hooks/useEntriesData.d.ts +2 -1
  403. package/dist/editor/hooks/useEntriesData.js +18 -4
  404. package/dist/editor/hooks/useEntryManager.d.ts +41 -2
  405. package/dist/editor/hooks/useEntryManager.js +227 -41
  406. package/dist/editor/hooks/useGroupManager.js +13 -16
  407. package/dist/editor/hooks/usePermissionManager.js +14 -6
  408. package/dist/editor/hooks/usePreviewMarks.d.ts +21 -0
  409. package/dist/editor/hooks/usePreviewMarks.js +33 -0
  410. package/dist/editor/hooks/useReferenceResolution.d.ts +10 -3
  411. package/dist/editor/hooks/useReferenceResolution.js +34 -177
  412. package/dist/editor/hooks/useSchemaManager.d.ts +25 -6
  413. package/dist/editor/hooks/useSchemaManager.js +97 -39
  414. package/dist/editor/hooks/useUserMetadata.d.ts +14 -4
  415. package/dist/editor/hooks/useUserMetadata.js +76 -47
  416. package/dist/editor/hooks/user-metadata-batcher.d.ts +8 -0
  417. package/dist/editor/hooks/user-metadata-batcher.js +33 -0
  418. package/dist/editor/media/AssetCard.d.ts +6 -7
  419. package/dist/editor/media/AssetCard.js +24 -31
  420. package/dist/editor/media/AssetListRow.d.ts +16 -0
  421. package/dist/editor/media/AssetListRow.js +41 -0
  422. package/dist/editor/media/CropStep.js +6 -1
  423. package/dist/editor/media/MediaLibrary.d.ts +4 -3
  424. package/dist/editor/media/MediaLibrary.js +11 -4
  425. package/dist/editor/media/MediaLibraryBody.d.ts +3 -3
  426. package/dist/editor/media/MediaLibraryBody.js +195 -80
  427. package/dist/editor/media/MediaLibrarySkeleton.d.ts +6 -0
  428. package/dist/editor/media/MediaLibrarySkeleton.js +14 -0
  429. package/dist/editor/media/crop-math.d.ts +3 -4
  430. package/dist/editor/media/crop-math.js +11 -22
  431. package/dist/editor/media/editor-image-src.d.ts +8 -0
  432. package/dist/editor/media/editor-image-src.js +10 -0
  433. package/dist/editor/media/format-bytes.d.ts +2 -0
  434. package/dist/editor/media/format-bytes.js +23 -0
  435. package/dist/editor/media/media-library-prefs.d.ts +23 -0
  436. package/dist/editor/media/media-library-prefs.js +49 -0
  437. package/dist/editor/media/media-library-view.d.ts +34 -0
  438. package/dist/editor/media/media-library-view.js +40 -0
  439. package/dist/editor/media/useAssetLibrary.d.ts +30 -0
  440. package/dist/editor/media/useAssetLibrary.js +126 -0
  441. package/dist/editor/media/useStableAssetOrder.d.ts +11 -0
  442. package/dist/editor/media/useStableAssetOrder.js +37 -0
  443. package/dist/editor/media/useThumbnailFailure.d.ts +6 -0
  444. package/dist/editor/media/useThumbnailFailure.js +16 -0
  445. package/dist/editor/permission-manager/GroupSelector.js +2 -2
  446. package/dist/editor/permission-manager/PermissionEditor.d.ts +1 -1
  447. package/dist/editor/permission-manager/PermissionEditor.js +15 -4
  448. package/dist/editor/permission-manager/PermissionLevelBadge.js +1 -1
  449. package/dist/editor/permission-manager/PermissionTree.d.ts +1 -1
  450. package/dist/editor/permission-manager/UserSelector.d.ts +1 -1
  451. package/dist/editor/permission-manager/UserSelector.js +3 -3
  452. package/dist/editor/permission-manager/index.js +12 -3
  453. package/dist/editor/permission-manager/types.d.ts +5 -2
  454. package/dist/editor/platform.d.ts +3 -0
  455. package/dist/editor/platform.js +9 -0
  456. package/dist/editor/preview-asset-base.d.ts +9 -0
  457. package/dist/editor/preview-asset-base.js +17 -0
  458. package/dist/editor/preview-bridge.d.ts +51 -27
  459. package/dist/editor/preview-bridge.js +103 -144
  460. package/dist/editor/preview-marks.d.ts +15 -0
  461. package/dist/editor/preview-marks.js +74 -0
  462. package/dist/editor/preview-path.d.ts +12 -0
  463. package/dist/editor/preview-path.js +45 -1
  464. package/dist/editor/preview-scale.d.ts +27 -0
  465. package/dist/editor/preview-scale.js +34 -0
  466. package/dist/editor/raw-asset-base.d.ts +5 -0
  467. package/dist/editor/raw-asset-base.js +14 -0
  468. package/dist/editor/relative-time.d.ts +4 -4
  469. package/dist/editor/relative-time.js +16 -8
  470. package/dist/editor/schema-editor/CollectionEditor.d.ts +20 -3
  471. package/dist/editor/schema-editor/CollectionEditor.js +361 -62
  472. package/dist/editor/schema-editor/EntryTypeEditor.d.ts +5 -1
  473. package/dist/editor/schema-editor/EntryTypeEditor.js +11 -6
  474. package/dist/editor/schema-editor/collection-draft.d.ts +22 -0
  475. package/dist/editor/schema-editor/collection-draft.js +40 -0
  476. package/dist/editor/schema-editor/index.d.ts +1 -1
  477. package/dist/editor/schema-label.d.ts +10 -0
  478. package/dist/editor/schema-label.js +17 -0
  479. package/dist/editor/settings-conflict.d.ts +5 -0
  480. package/dist/editor/settings-conflict.js +8 -0
  481. package/dist/editor/shell/ActivityRail.d.ts +37 -0
  482. package/dist/editor/shell/ActivityRail.js +91 -0
  483. package/dist/editor/shell/EditorShell.d.ts +17 -0
  484. package/dist/editor/shell/EditorShell.js +31 -0
  485. package/dist/editor/shell/PaneLayout.d.ts +28 -0
  486. package/dist/editor/shell/PaneLayout.js +116 -0
  487. package/dist/editor/shell/SidePanelHost.d.ts +35 -0
  488. package/dist/editor/shell/SidePanelHost.js +184 -0
  489. package/dist/editor/shell/TopBar.d.ts +12 -0
  490. package/dist/editor/shell/TopBar.js +14 -0
  491. package/dist/editor/shell/host-chrome.d.ts +16 -0
  492. package/dist/editor/shell/host-chrome.js +69 -0
  493. package/dist/editor/slug.d.ts +16 -0
  494. package/dist/editor/slug.js +43 -0
  495. package/dist/editor/theme.d.ts +2 -1
  496. package/dist/editor/theme.js +314 -13
  497. package/dist/editor/unanswered.d.ts +17 -0
  498. package/dist/editor/unanswered.js +26 -0
  499. package/dist/editor/unavailable-entry-type.d.ts +20 -0
  500. package/dist/editor/unavailable-entry-type.js +28 -0
  501. package/dist/editor/undo-removal.d.ts +57 -0
  502. package/dist/editor/undo-removal.js +163 -0
  503. package/dist/editor/user-display.d.ts +4 -0
  504. package/dist/editor/user-display.js +5 -0
  505. package/dist/editor/utils/confirm-modal.d.ts +8 -0
  506. package/dist/editor/utils/confirm-modal.js +12 -0
  507. package/dist/editor/utils/editor-errors.d.ts +19 -0
  508. package/dist/editor/utils/editor-errors.js +32 -0
  509. package/dist/editor/utils/focus-return.d.ts +56 -0
  510. package/dist/editor/utils/focus-return.js +106 -0
  511. package/dist/entry-link-resolver.d.ts +11 -1
  512. package/dist/entry-link-resolver.js +65 -5
  513. package/dist/entry-schema-registry.d.ts +3 -3
  514. package/dist/entry-schema-registry.js +7 -4
  515. package/dist/entry-schema.d.ts +49 -3
  516. package/dist/entry-schema.js +18 -0
  517. package/dist/git-manager.d.ts +172 -10
  518. package/dist/git-manager.js +449 -107
  519. package/dist/github-service.d.ts +39 -2
  520. package/dist/github-service.js +101 -7
  521. package/dist/http/handler.js +74 -9
  522. package/dist/http/types.d.ts +2 -0
  523. package/dist/http/worker-not-ready.d.ts +9 -4
  524. package/dist/http/worker-not-ready.js +59 -6
  525. package/dist/index.d.ts +2 -0
  526. package/dist/index.js +3 -0
  527. package/dist/item-keys.d.ts +46 -0
  528. package/dist/item-keys.js +235 -0
  529. package/dist/operating-mode/editor-mode-check.d.ts +15 -0
  530. package/dist/operating-mode/editor-mode-check.js +24 -0
  531. package/dist/operating-mode/mode-env.d.ts +13 -14
  532. package/dist/operating-mode/mode-env.js +13 -14
  533. package/dist/operating-mode/types.d.ts +2 -2
  534. package/dist/paths/branch.d.ts +0 -1
  535. package/dist/paths/branch.js +1 -8
  536. package/dist/paths/index.d.ts +1 -1
  537. package/dist/paths/index.js +1 -1
  538. package/dist/paths/validation.js +0 -2
  539. package/dist/preview.d.ts +8 -0
  540. package/dist/preview.js +7 -0
  541. package/dist/reference-resolver.js +1 -0
  542. package/dist/resolve-canopy-user.d.ts +1 -1
  543. package/dist/resolve-canopy-user.js +1 -1
  544. package/dist/schema/meta-loader.d.ts +18 -8
  545. package/dist/schema/meta-loader.js +42 -9
  546. package/dist/schema/registry-fingerprint.d.ts +14 -0
  547. package/dist/schema/registry-fingerprint.js +63 -0
  548. package/dist/schema/resolver.d.ts +7 -4
  549. package/dist/schema/resolver.js +7 -6
  550. package/dist/schema/schema-store.d.ts +7 -10
  551. package/dist/schema/schema-store.js +13 -11
  552. package/dist/schema/schema-unavailable-error.d.ts +11 -0
  553. package/dist/schema/schema-unavailable-error.js +15 -0
  554. package/dist/schema/types.d.ts +22 -0
  555. package/dist/schema-registry-record.d.ts +35 -0
  556. package/dist/schema-registry-record.js +134 -0
  557. package/dist/server.d.ts +79 -9
  558. package/dist/server.js +62 -8
  559. package/dist/services.d.ts +33 -5
  560. package/dist/services.js +155 -37
  561. package/dist/settings-workspace.d.ts +23 -3
  562. package/dist/settings-workspace.js +159 -45
  563. package/dist/stamp-on-publish.d.ts +36 -0
  564. package/dist/stamp-on-publish.js +71 -0
  565. package/dist/static/index.d.ts +58 -5
  566. package/dist/static/index.js +133 -3
  567. package/dist/static/seo.d.ts +5 -5
  568. package/dist/static/seo.js +5 -5
  569. package/dist/submission-attribution.d.ts +8 -0
  570. package/dist/submission-attribution.js +22 -0
  571. package/dist/system-users.d.ts +12 -0
  572. package/dist/system-users.js +12 -0
  573. package/dist/task-queue/cms-task-queue.d.ts +1 -1
  574. package/dist/task-queue/cms-task-queue.js +1 -1
  575. package/dist/task-queue/index.d.ts +1 -1
  576. package/dist/task-queue/index.js +1 -1
  577. package/dist/task-queue/task-queue.d.ts +6 -0
  578. package/dist/task-queue/task-queue.js +29 -0
  579. package/dist/task-queue/worker-status.d.ts +35 -9
  580. package/dist/task-queue/worker-status.js +84 -17
  581. package/dist/types.d.ts +90 -9
  582. package/dist/url-collision.js +3 -3
  583. package/dist/url-exclusivity-fixtures.d.ts +8 -1
  584. package/dist/url-exclusivity-fixtures.js +11 -1
  585. package/dist/user.js +2 -1
  586. package/dist/utils/atomic-write.js +2 -1
  587. package/dist/utils/base-branch.d.ts +13 -0
  588. package/dist/utils/base-branch.js +23 -0
  589. package/dist/utils/content-serialize.d.ts +15 -7
  590. package/dist/utils/content-serialize.js +353 -51
  591. package/dist/utils/content-write-lock.d.ts +6 -1
  592. package/dist/utils/content-write-lock.js +21 -6
  593. package/dist/utils/debug.d.ts +1 -1
  594. package/dist/utils/debug.js +5 -3
  595. package/dist/utils/error.js +13 -2
  596. package/dist/utils/escape-text.d.ts +7 -0
  597. package/dist/utils/escape-text.js +27 -0
  598. package/dist/utils/fs.d.ts +12 -4
  599. package/dist/utils/fs.js +18 -5
  600. package/dist/utils/git.d.ts +21 -1
  601. package/dist/utils/git.js +63 -8
  602. package/dist/utils/json-source-splice.d.ts +14 -0
  603. package/dist/utils/json-source-splice.js +120 -0
  604. package/dist/utils/markdown-body-splice.d.ts +39 -0
  605. package/dist/utils/markdown-body-splice.js +421 -0
  606. package/dist/utils/occ-json-write.js +18 -12
  607. package/dist/utils/provision-log.d.ts +25 -0
  608. package/dist/utils/provision-log.js +49 -0
  609. package/dist/utils/provisioning-lock.d.ts +32 -1
  610. package/dist/utils/provisioning-lock.js +78 -32
  611. package/dist/utils/sanitize-href.d.ts +9 -23
  612. package/dist/utils/sanitize-href.js +14 -28
  613. package/dist/utils/title-field.d.ts +10 -0
  614. package/dist/utils/title-field.js +47 -0
  615. package/dist/utils/yaml-source-splice.d.ts +58 -0
  616. package/dist/utils/yaml-source-splice.js +515 -0
  617. package/dist/validation/block-structural-keys.d.ts +1 -1
  618. package/dist/validation/block-structural-keys.js +1 -1
  619. package/dist/validation/deletion-checker.d.ts +21 -29
  620. package/dist/validation/deletion-checker.js +41 -117
  621. package/dist/validation/entry-validator.d.ts +6 -10
  622. package/dist/validation/entry-validator.js +19 -26
  623. package/dist/validation/field-traversal.d.ts +22 -0
  624. package/dist/validation/field-traversal.js +39 -8
  625. package/dist/validation/markdown-safety.d.ts +68 -0
  626. package/dist/validation/markdown-safety.js +596 -0
  627. package/dist/validation/mdx-allowlist.d.ts +55 -0
  628. package/dist/validation/mdx-allowlist.js +183 -0
  629. package/dist/validation/reference-validator.d.ts +2 -0
  630. package/dist/validation/reference-validator.js +3 -0
  631. package/dist/version.d.ts +1 -1
  632. package/dist/version.js +1 -1
  633. package/dist/worker/branch-policy.d.ts +124 -0
  634. package/dist/worker/branch-policy.js +243 -0
  635. package/dist/worker/bundle-header.d.ts +117 -0
  636. package/dist/worker/bundle-header.js +253 -0
  637. package/dist/worker/cms-worker.d.ts +236 -142
  638. package/dist/worker/cms-worker.js +772 -285
  639. package/dist/worker/gateway-egress.d.ts +43 -0
  640. package/dist/worker/gateway-egress.js +209 -0
  641. package/dist/worker/gateway-instance.d.ts +42 -0
  642. package/dist/worker/gateway-instance.js +129 -0
  643. package/dist/worker/git-process.d.ts +81 -0
  644. package/dist/worker/git-process.js +234 -0
  645. package/dist/worker/git-sync.d.ts +34 -17
  646. package/dist/worker/git-sync.js +394 -131
  647. package/dist/worker/github-auth.d.ts +9 -9
  648. package/dist/worker/github-auth.js +13 -15
  649. package/dist/worker/github-gateway-http.d.ts +62 -0
  650. package/dist/worker/github-gateway-http.js +977 -0
  651. package/dist/worker/github-gateway-wire.d.ts +590 -0
  652. package/dist/worker/github-gateway-wire.js +488 -0
  653. package/dist/worker/github-gateway.d.ts +238 -0
  654. package/dist/worker/github-gateway.js +726 -0
  655. package/dist/worker/github-mirror-upkeep.d.ts +75 -0
  656. package/dist/worker/github-mirror-upkeep.js +266 -0
  657. package/dist/worker/github-mirror.d.ts +364 -0
  658. package/dist/worker/github-mirror.js +1030 -0
  659. package/dist/worker/github-transfer.d.ts +56 -0
  660. package/dist/worker/github-transfer.js +444 -0
  661. package/dist/worker/history-rewrite.d.ts +4 -5
  662. package/dist/worker/history-rewrite.js +12 -17
  663. package/dist/worker/provisioned-workspace.d.ts +5 -5
  664. package/dist/worker/provisioned-workspace.js +5 -5
  665. package/dist/worker/rebase.d.ts +1 -1
  666. package/dist/worker/rebase.js +58 -54
  667. package/dist/worker/remote-git-maintenance.d.ts +3 -0
  668. package/dist/worker/remote-git-maintenance.js +12 -0
  669. package/dist/worker/schema-gate.d.ts +49 -0
  670. package/dist/worker/schema-gate.js +226 -0
  671. package/dist/worker/self-checks.d.ts +107 -0
  672. package/dist/worker/self-checks.js +358 -0
  673. package/dist/worker/shared-repo-git.d.ts +96 -0
  674. package/dist/worker/shared-repo-git.js +459 -0
  675. package/dist/worker/sparse-cone.d.ts +20 -0
  676. package/dist/worker/sparse-cone.js +136 -0
  677. package/dist/worker/stale-mirror.d.ts +82 -0
  678. package/dist/worker/stale-mirror.js +130 -0
  679. package/dist/worker/task-runner.d.ts +5 -3
  680. package/dist/worker/task-runner.js +287 -186
  681. package/dist/worker/worker-context.d.ts +36 -37
  682. package/package.json +35 -7
  683. package/dist/editor/EditorPanes.d.ts +0 -10
  684. package/dist/editor/EditorPanes.js +0 -98
  685. package/dist/editor/components/EditorFooter.d.ts +0 -11
  686. package/dist/editor/components/EditorFooter.js +0 -9
  687. package/dist/editor/components/EditorSidebar.d.ts +0 -67
  688. package/dist/editor/components/EditorSidebar.js +0 -22
@@ -1,130 +1,82 @@
1
+ import { type Ref } from 'react';
1
2
  import type { OperatingMode } from '../../operating-mode/index.js';
2
3
  import type { BranchStatus } from '../../types.js';
3
4
  import type { EditorEntry } from '../Editor.js';
4
5
  import type { LogicalPath } from '../../paths/types.js';
6
+ import type { BreadcrumbSegment } from '../editor-utils.js';
7
+ import type { SaveAllProgress } from '../hooks/save-all.js';
5
8
  export interface EditorHeaderProps {
6
- /**
7
- * Site title displayed in the top-left.
8
- */
9
- siteTitle: string;
10
- /**
11
- * Optional site subtitle displayed below the title.
12
- */
13
- siteSubtitle?: string;
14
- /**
15
- * Main header title displayed in the center.
16
- */
17
- headerTitle: string;
18
- /**
19
- * Currently selected entry.
20
- */
21
9
  currentEntry: EditorEntry | undefined;
22
- /**
23
- * Current branch name.
24
- */
25
10
  branchName: string;
26
- /**
27
- * Operating mode.
28
- */
29
11
  operatingMode: OperatingMode;
30
- /**
31
- * Whether operations are currently in progress.
32
- */
12
+ /** Whether operations are currently in progress. */
33
13
  busy: boolean;
34
- /**
35
- * Breadcrumb segments to display.
36
- */
37
- breadcrumbSegments: string[];
38
- /**
39
- * List of edited files.
40
- */
14
+ /** The crumbs before the open entry's own. */
15
+ breadcrumbSegments: BreadcrumbSegment[];
16
+ /** The listed entries with unsaved changes on the branch. */
41
17
  editedFiles: Array<{
42
18
  path: LogicalPath;
43
19
  label: string;
44
20
  }>;
45
- /**
46
- * Number of modified files.
47
- */
21
+ /** Entries with unsaved changes on the branch. */
48
22
  modifiedCount: number;
49
- /**
50
- * Number of unresolved comments.
51
- */
52
- unresolvedCommentCount: number;
53
- /**
54
- * Unresolved comments (for filtering).
55
- */
56
- comments: Array<{
57
- resolved: boolean;
58
- }>;
59
- /**
60
- * Callback to open the entry navigator.
61
- */
23
+ /** Opens the content panel. */
62
24
  onNavigatorOpen: () => void;
63
- /**
64
- * Callback to reload the current file.
65
- */
25
+ /** Opens the content panel on a collection. */
26
+ onCollectionOpen: (collectionPath: string) => void;
27
+ /** The entry menu's trigger. */
28
+ navigatorToggleRef?: Ref<HTMLButtonElement>;
29
+ /** The branch pill. */
30
+ branchToggleRef?: Ref<HTMLButtonElement>;
31
+ /** Replaces the open entry with the server's copy. */
66
32
  onFileReload: () => void;
67
- /**
68
- * Callback to discard the current file draft.
69
- */
70
33
  onFileDiscardDraft: () => void;
71
- /**
72
- * Callback when an entry is selected.
73
- */
74
- onEntrySelect: (id: string) => void;
75
- /**
76
- * Callback to reload all branch data.
77
- */
34
+ /** Opens the open entry's rename dialog. */
35
+ onEntryRename: () => void;
36
+ /** Asks to delete the open entry. */
37
+ onEntryDelete: () => void;
38
+ /** The "All content" crumb. */
39
+ allContentRef?: Ref<HTMLButtonElement>;
40
+ onEntrySelect: (path: LogicalPath) => void;
41
+ /** Re-reads the branch and its entry list, keeping drafts. */
78
42
  onBranchReloadData: () => void;
79
- /**
80
- * Callback to discard all drafts.
81
- */
82
43
  onBranchDiscardDrafts: () => void;
83
- /**
84
- * Callback to open the branch manager.
85
- */
86
44
  onBranchManagerOpen: () => void;
87
- /**
88
- * Callback to open the comments panel.
89
- */
90
- onCommentsPanelOpen: () => void;
91
- /**
92
- * Callback to save the current file.
93
- */
94
45
  onSave: () => void;
95
- /**
96
- * Callback to submit/publish the branch.
97
- */
46
+ onSaveAll: () => void;
47
+ saveAllProgress: SaveAllProgress | null;
48
+ /** A Save of the open entry is in flight. */
49
+ saving?: boolean;
50
+ /** Rises each time a single Save lands, whichever entry it saved. */
51
+ savedSignal?: number;
52
+ /** The last Save that landed saved the open entry. */
53
+ savedHere?: boolean;
54
+ /** The branch's entry list failed to load and none is held. */
55
+ entryListFailed?: boolean;
98
56
  onSubmit: () => void;
99
- /**
100
- * Whether the current entry has unsaved changes.
101
- */
57
+ onWithdraw: () => void;
58
+ /** The open entry has unsaved changes it could save. */
102
59
  hasUnsavedChanges: boolean;
103
- /**
104
- * Current branch status (undefined if unknown).
105
- */
60
+ /** The open entry has a draft, savable or not (a read-only branch's still discards). */
61
+ entryHasDraft?: boolean;
62
+ /** Writing drafts to localStorage failed, so they live only in this tab. */
63
+ draftStorageFailed?: boolean;
64
+ /** The open entry can't be edited by this user (a path rule). */
65
+ entryReadOnly?: boolean;
66
+ /** The open entry's type has no schema in the running code. */
67
+ entryUnavailable?: boolean;
68
+ /** Current branch status (undefined if unknown). */
106
69
  branchStatus: BranchStatus | undefined;
107
- /**
108
- * Callback to withdraw the branch.
109
- */
110
- onWithdraw: () => void;
111
- /**
112
- * Current user context for permission checks.
113
- */
70
+ /** Current user context for permission checks. */
114
71
  userContext?: {
115
72
  userId: string;
116
73
  groups?: string[];
117
74
  };
118
- /**
119
- * Branch creator user ID.
120
- */
121
75
  branchCreatedBy?: string;
122
- /**
123
- * Branch access control lists.
124
- */
125
76
  branchAccess?: {
126
77
  allowedUsers?: string[];
127
78
  allowedGroups?: string[];
79
+ managerOrAdminAllowed?: boolean;
128
80
  };
129
81
  /**
130
82
  * Whether the current branch is the protected base branch (see
@@ -132,20 +84,18 @@ export interface EditorHeaderProps {
132
84
  * stays, as the recovery path). Default false.
133
85
  */
134
86
  branchIsProtected?: boolean;
135
- /**
136
- * Whether the current branch is read-only (protected base branch in prod).
137
- * Disables Save and shows the "create a branch" banner below. Default false.
138
- */
87
+ /** Whether the current branch is read-only (protected base branch in prod); disables Save. */
139
88
  branchReadOnly?: boolean;
89
+ /** Server-computed: content writes are rejected on this branch; see `branchLockState`. */
90
+ branchWriteBlocked?: boolean;
140
91
  /**
141
- * Server-computed: content writes are rejected on this branch, for either
142
- * reason (base-branch read-only, or a status past 'editing'). Combined with
143
- * `branchReadOnly` to pick which of the two banners to show. Default false.
92
+ * No branch details yet (loading, or the list failed and the banner says so): the fail-closed
93
+ * lock defaults are guesses, so neither the chip nor the status names them.
144
94
  */
145
- branchWriteBlocked?: boolean;
95
+ branchLoading?: boolean;
146
96
  }
147
97
  /**
148
- * Header component for the Editor.
149
- * Contains site info, file navigation, breadcrumbs, branch selector, comments button, and action buttons.
98
+ * The top bar's contents: the breadcrumb with the entry menu and "Read-only" chip, then the branch
99
+ * pill, Submit or Withdraw, and Save with Save all.
150
100
  */
151
- export declare const EditorHeader: import("react").ForwardRefExoticComponent<EditorHeaderProps & import("react").RefAttributes<HTMLDivElement>>;
101
+ export declare function EditorHeader({ currentEntry, branchName, operatingMode, busy, breadcrumbSegments, editedFiles, modifiedCount, onNavigatorOpen, onCollectionOpen, navigatorToggleRef, branchToggleRef, onFileReload, onFileDiscardDraft, onEntryRename, onEntryDelete, allContentRef, onEntrySelect, onBranchReloadData, onBranchDiscardDrafts, onBranchManagerOpen, onSave, onSaveAll, saveAllProgress, saving, savedSignal, savedHere, entryListFailed, onSubmit, onWithdraw, hasUnsavedChanges, entryHasDraft, draftStorageFailed, entryReadOnly, entryUnavailable, branchStatus, userContext, branchCreatedBy, branchAccess, branchIsProtected, branchReadOnly, branchWriteBlocked, branchLoading, }: EditorHeaderProps): import("react/jsx-runtime").JSX.Element;
@@ -1,134 +1,133 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { forwardRef } from 'react';
3
- import { Alert, Badge, Box, Button, Group, Menu, Paper, Stack, Text, Title, Tooltip, } from '@mantine/core';
4
- import { IconFolderOpen, IconChevronDown, IconGitBranch, IconLock } from '@tabler/icons-react';
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, Tooltip } from '@mantine/core';
5
3
  import { clientOperatingStrategy } from '../../operating-mode/client.js';
6
- import { isAdmin, isReviewer } from '../../authorization/helpers.js';
4
+ import { isAdmin, isLockedOutOfBranch, isReviewer } from '../../authorization/helpers.js';
5
+ import { branchStatusPresentation } from '../branch-status.js';
6
+ import { EDITOR_ACTIONS } from '../copy.js';
7
+ import { SYSTEM_USER_ID } from '../../system-users.js';
8
+ import { TopBar } from '../shell/TopBar.js';
9
+ import { branchLockState } from './BranchLockBanner.js';
10
+ import { BranchPill } from './BranchPill.js';
11
+ import { EntryBreadcrumb } from './EntryBreadcrumb.js';
12
+ import { SaveSplitButton } from './SaveSplitButton.js';
7
13
  /**
8
- * Status color map matching BranchManager.tsx pattern.
9
- * Returns the Mantine color string for a given branch status.
14
+ * The top bar's contents: the breadcrumb with the entry menu and "Read-only" chip, then the branch
15
+ * pill, Submit or Withdraw, and Save with Save all.
10
16
  */
11
- const getStatusColor = (status) => {
12
- const statusColorMap = {
13
- editing: 'brand',
14
- submitted: 'green',
15
- approved: 'teal',
16
- archived: 'gray',
17
- };
18
- return statusColorMap[status] ?? 'gray';
19
- };
20
- /**
21
- * Header component for the Editor.
22
- * Contains site info, file navigation, breadcrumbs, branch selector, comments button, and action buttons.
23
- */
24
- export const EditorHeader = forwardRef(function EditorHeader({ siteTitle, siteSubtitle, headerTitle, currentEntry, branchName, operatingMode, busy, breadcrumbSegments, editedFiles, modifiedCount, unresolvedCommentCount: _, comments, onNavigatorOpen, onFileReload, onFileDiscardDraft, onEntrySelect, onBranchReloadData, onBranchDiscardDrafts, onBranchManagerOpen, onCommentsPanelOpen, onSave, onSubmit, hasUnsavedChanges, branchStatus, onWithdraw, userContext, branchCreatedBy, branchAccess, branchIsProtected = false, branchReadOnly = false, branchWriteBlocked = false, }, ref) {
25
- // `branchWriteBlocked` is the server's own answer (getBranchProtection), so
26
- // Save is never enabled for a write the API would reject; a client-side
27
- // derivation could drift from it. `branchReadOnly` only picks which banner
28
- // to show -- base-branch read-only takes precedence over a workflow status
29
- // lock.
30
- const statusLocked = branchWriteBlocked && !branchReadOnly;
31
- // Covers two cases where `branchStatus` can't be trusted to describe the lock
32
- // honestly: branch data still loading (`branchStatus` is undefined, so the
33
- // banner would otherwise interpolate "Branch is undefined...") and version
34
- // skew (an old server omits `branchWriteBlocked` while still reporting
35
- // status: 'editing', which would otherwise assert a lock the status
36
- // contradicts). In both cases the banner says data is unavailable instead.
37
- const branchDataUnavailable = statusLocked && (branchStatus === undefined || branchStatus === 'editing');
38
- return (_jsx(Paper, { ref: ref, shadow: "md", withBorder: true, radius: 0, px: 0, py: 0, style: {
39
- position: 'fixed',
40
- top: 0,
41
- left: 0,
42
- right: 0,
43
- zIndex: 70,
44
- }, children: _jsxs(Box, { px: "md", py: "sm", children: [_jsxs(Group, { justify: "space-between", align: "center", wrap: "nowrap", children: [_jsxs(Stack, { gap: 2, style: { minWidth: 0 }, children: [_jsx(Title, { order: 5, style: { lineHeight: 1.1 }, children: siteTitle }), siteSubtitle && (_jsx(Text, { size: "xs", c: "dimmed", children: siteSubtitle }))] }), _jsxs(Stack, { gap: 6, style: { minWidth: 0, flex: 1, alignItems: 'center' }, children: [_jsx(Title, { order: 4, style: { lineHeight: 1.1 }, children: headerTitle }), _jsxs(Group, { gap: "sm", wrap: "wrap", align: "center", style: { minWidth: 0, justifyContent: 'center' }, children: [_jsxs(Menu, { withinPortal: true, shadow: "sm", children: [_jsx(Menu.Target, { children: _jsx(Button, { "data-testid": "file-dropdown-button", variant: "outline", color: "gray", size: "xs", leftSection: _jsx(IconFolderOpen, { size: 16 }), rightSection: _jsx(IconChevronDown, { size: 14 }), children: currentEntry?.label ?? 'No file selected' }) }), _jsxs(Menu.Dropdown, { children: [_jsx(Menu.Item, { onClick: onFileReload, disabled: !branchName || !currentEntry, children: "Reload File" }), _jsx(Menu.Item, { "data-testid": "discard-file-draft-menu-item", onClick: onFileDiscardDraft, disabled: !currentEntry, children: "Discard File Draft" }), _jsx(Menu.Divider, {}), _jsx(Menu.Item, { "data-testid": "all-files-menu-item", onClick: onNavigatorOpen, children: "All Files" }), _jsx(Menu.Divider, {}), _jsx(Menu.Label, { children: "Recently modified" }), editedFiles.slice(0, 3).length === 0 ? (_jsx(Menu.Item, { disabled: true, children: "<none>" })) : (editedFiles.slice(0, 3).map((file) => (_jsx(Menu.Item, { onClick: () => {
45
- onEntrySelect(file.path);
46
- onNavigatorOpen();
47
- }, children: file.label }, file.path))))] })] }), _jsx(Group, { gap: 4, wrap: "wrap", align: "center", style: { minWidth: 0 }, children: breadcrumbSegments.map((segment, idx) => (_jsxs(Group, { gap: 4, align: "center", wrap: "nowrap", children: [idx > 0 && (_jsx(Text, { size: "xs", c: "dimmed", children: "/" })), _jsx(Button, { variant: "subtle", size: "xs", px: "xs", onClick: onNavigatorOpen, children: segment })] }, `${segment}-${idx}`))) }), _jsxs(Menu, { withinPortal: true, shadow: "sm", children: [_jsx(Menu.Target, { children: _jsx(Button, { variant: "outline", color: "gray", size: "xs", leftSection: _jsx(IconGitBranch, { size: 16 }), rightSection: _jsx(IconChevronDown, { size: 14 }), loading: !branchName && busy, "data-testid": "branch-dropdown-button", children: branchName || (busy ? 'Loading branches…' : 'No branch selected') }) }), _jsxs(Menu.Dropdown, { "data-testid": "branch-menu", children: [_jsx(Menu.Item, { onClick: onBranchReloadData, disabled: !branchName, children: "Reload All Files" }), _jsx(Menu.Item, { onClick: onBranchDiscardDrafts, disabled: !branchName, children: "Discard All File Drafts" }), _jsx(Menu.Divider, {}), _jsx(Menu.Item, { onClick: onBranchManagerOpen, "data-testid": "manage-branches-menu-item", children: "Change / Manage Branches" }), _jsx(Menu.Divider, {}), _jsx(Menu.Label, { children: `${modifiedCount} file${modifiedCount === 1 ? '' : 's'} modified` }), editedFiles.length === 0 ? (_jsx(Menu.Item, { disabled: true, children: "No edited files yet" })) : (editedFiles.map((file) => (_jsx(Menu.Item, { onClick: () => {
48
- onEntrySelect(file.path);
49
- onNavigatorOpen();
50
- }, children: file.label }, `branch-mod-${file.path}`))))] })] }), clientOperatingStrategy(operatingMode ?? 'prod').supportsStatusBadge() &&
51
- branchName &&
52
- branchStatus && (_jsx(Badge, { color: getStatusColor(branchStatus), variant: "light", size: "sm", "data-testid": `header-status-badge-${branchStatus}`, children: branchStatus })), clientOperatingStrategy(operatingMode ?? 'prod').supportsComments() &&
53
- branchName && (_jsxs(Button, { variant: "outline", color: "gray", size: "xs", onClick: onCommentsPanelOpen, style: { position: 'relative' }, "data-testid": "comments-button", children: ["Comments", comments.filter((t) => !t.resolved).length > 0 && (_jsx("span", { style: {
54
- position: 'absolute',
55
- top: -6,
56
- right: -6,
57
- background: 'var(--mantine-color-grape-6)',
58
- color: 'white',
59
- borderRadius: '50%',
60
- width: 18,
61
- height: 18,
62
- fontSize: 10,
63
- display: 'flex',
64
- alignItems: 'center',
65
- justifyContent: 'center',
66
- fontWeight: 600,
67
- }, children: comments.filter((t) => !t.resolved).length }))] }))] })] }), _jsxs(Group, { gap: "xs", wrap: "nowrap", children: [_jsx(Tooltip, { label: branchReadOnly
68
- ? 'The base branch is read-only'
69
- : branchDataUnavailable
70
- ? 'Branch details are still loading — saving is disabled until they arrive'
71
- : statusLocked
72
- ? branchStatus === 'submitted'
73
- ? 'This branch is submitted for review — withdraw it to make changes'
74
- : `This branch is ${branchStatus} — content is read-only`
75
- : !hasUnsavedChanges && currentEntry
76
- ? 'No changes to save'
77
- : '', disabled: !branchReadOnly && !statusLocked && (hasUnsavedChanges || !currentEntry), children: _jsx(Button, { "data-testid": "save-button", variant: "light", size: "sm", onClick: onSave, disabled: !branchName ||
78
- !currentEntry ||
79
- busy ||
80
- !hasUnsavedChanges ||
81
- branchReadOnly ||
82
- statusLocked, children: "Save File" }) }), (() => {
83
- const isSubmitted = branchStatus === 'submitted';
84
- const isEditing = branchStatus === 'editing';
85
- // 'approved' withdraws too -- it is that status's only
86
- // non-destructive exit now that the submit status gate refuses a
87
- // non-editing branch (api/branch-status.ts, api/branch-withdraw.ts).
88
- // This button is a two-state toggle, so every withdrawable status
89
- // has to drive the withdraw side of it, not just 'submitted'.
90
- const isWithdrawable = isSubmitted || branchStatus === 'approved';
91
- // The protected base branch can never be submitted for review (both
92
- // modes); hide the button entirely rather than showing it disabled.
93
- // Withdraw stays available as the recovery path for a base branch
94
- // wrongly stuck in 'submitted'.
95
- if (branchIsProtected && !isWithdrawable)
96
- return null;
97
- // Who may submit/withdraw: creator, ACL access, the system branch, or an
98
- // admin/reviewer -- Admins/Reviewers must be able to withdraw a protected
99
- // base branch stuck in 'submitted' even without ACL access. Mirrors the
100
- // server's canPerformWorkflowAction (BranchManager.tsx), which is the
101
- // actual enforcer; this only decides whether to show the control disabled.
102
- const userIsCreator = userContext?.userId === branchCreatedBy;
103
- const isSystemBranch = branchCreatedBy === 'canopycms-system' && !branchIsProtected;
104
- const userInACL = userContext &&
105
- branchAccess &&
106
- (branchAccess.allowedUsers?.includes(userContext.userId) ||
107
- userContext.groups?.some((g) => branchAccess.allowedGroups?.includes(g)));
108
- const userIsPrivileged = !!userContext &&
109
- (isAdmin(userContext.groups ?? []) || isReviewer(userContext.groups ?? []));
110
- const userHasPermission = userIsCreator || userInACL || isSystemBranch || userIsPrivileged;
111
- // A status with no available transition (today: 'archived') is a
112
- // separate condition from lacking permission, and conflating them
113
- // sent people to an admin to fix a non-permissions problem.
114
- const statusHasAction = isEditing || isWithdrawable;
115
- const canPerformAction = userHasPermission && statusHasAction;
116
- return (_jsx(Tooltip, { label:
117
- // No branch data (`branchStatus === undefined`) must not be
118
- // interpolated raw into this label. Guarded explicitly here rather
119
- // than left to the early return above, which hides this button
120
- // today only as a side effect of `branchIsProtected`'s `?? true`
121
- // default -- not a guarantee this arm stays unreachable.
122
- branchStatus === undefined
123
- ? 'Branch data could not be loaded, so no submit or withdraw action is available'
124
- : !statusHasAction
125
- ? `This branch is ${branchStatus} and has no submit or withdraw action available`
126
- : !userHasPermission
127
- ? 'You do not have permission to submit or withdraw this branch'
128
- : '', disabled: canPerformAction, children: _jsx(Button, { size: "sm", color: isWithdrawable ? 'orange' : 'brand', onClick: isWithdrawable ? onWithdraw : onSubmit, disabled: !branchName || busy || !canPerformAction, "data-testid": isWithdrawable ? 'withdraw-button' : 'submit-button', children: isWithdrawable ? 'Withdraw Branch...' : 'Submit Branch...' }) }));
129
- })()] })] }), branchReadOnly && (_jsx(Alert, { icon: _jsx(IconLock, { size: 16 }), color: "yellow", variant: "light", mt: "sm", "data-testid": "protected-branch-banner", children: _jsxs(Group, { justify: "space-between", align: "center", gap: "sm", wrap: "wrap", children: [_jsx(Text, { size: "sm", children: `You are viewing the protected base branch "${branchName}". Content is read-only — create a branch to make changes.` }), _jsx(Button, { size: "xs", variant: "light", color: "yellow", onClick: onBranchManagerOpen, children: "Create a branch" })] }) })), statusLocked && (_jsx(Alert, { icon: _jsx(IconLock, { size: 16 }), color: "yellow", variant: "light", mt: "sm", "data-testid": "status-locked-banner", children: _jsxs(Group, { justify: "space-between", align: "center", gap: "sm", wrap: "wrap", children: [_jsx(Text, { size: "sm", children: branchDataUnavailable
130
- ? `Branch details for "${branchName}" could not be loaded, so content is locked until they arrive. Use Manage Branches to retry.`
131
- : branchStatus === 'submitted'
132
- ? `Branch "${branchName}" is submitted for review and locked for edits. Use Withdraw Branch above to resume editing.`
133
- : `Branch "${branchName}" is ${branchStatus} — content is read-only.` }), _jsx(Button, { size: "xs", variant: "light", color: "yellow", onClick: onBranchManagerOpen, children: "Manage Branches" })] }) }))] }) }));
134
- });
17
+ export function EditorHeader({ currentEntry, branchName, operatingMode, busy, breadcrumbSegments, editedFiles, modifiedCount, onNavigatorOpen, onCollectionOpen, navigatorToggleRef, branchToggleRef, onFileReload, onFileDiscardDraft, onEntryRename, onEntryDelete, allContentRef, onEntrySelect, onBranchReloadData, onBranchDiscardDrafts, onBranchManagerOpen, onSave, onSaveAll, saveAllProgress, saving = false, savedSignal, savedHere = false, entryListFailed = false, onSubmit, onWithdraw, hasUnsavedChanges, entryHasDraft = hasUnsavedChanges, draftStorageFailed = false, entryReadOnly = false, entryUnavailable = false, branchStatus, userContext, branchCreatedBy, branchAccess, branchIsProtected = false, branchReadOnly = false, branchWriteBlocked = false, branchLoading = false, }) {
18
+ const { statusLocked, branchDataUnavailable } = branchLockState({
19
+ branchStatus,
20
+ branchReadOnly,
21
+ branchWriteBlocked,
22
+ });
23
+ // Why the branch takes no writes, with the way forward; shared by Save, Save all and the chip.
24
+ const branchLockReason = branchReadOnly
25
+ ? 'The base branch is read-only. Create a branch to make changes.'
26
+ : branchDataUnavailable
27
+ ? 'Branch details could not be loaded. Use "Switch branch…" to retry.'
28
+ : statusLocked
29
+ ? branchStatus === 'submitted'
30
+ ? 'This branch is in review. Withdraw it to make changes.'
31
+ : branchStatus === 'approved'
32
+ ? 'This branch is approved. Withdraw it to make changes.'
33
+ : `This branch is ${branchStatus}. Its content is read-only.`
34
+ : undefined;
35
+ const entryLockReason = entryReadOnly
36
+ ? "You don't have edit access to this entry. Ask a CanopyCMS admin to grant it."
37
+ : undefined;
38
+ // The Tooltip hides it while the editor is busy.
39
+ const saveBlockedReason = branchLockReason ??
40
+ (!branchName
41
+ ? 'Open a branch first.'
42
+ : !currentEntry
43
+ ? 'Open an entry to save it.'
44
+ : (entryLockReason ?? (!hasUnsavedChanges ? 'No changes to save.' : '')));
45
+ const presentation = branchStatusPresentation(branchStatus, branchIsProtected);
46
+ const status = !branchLoading &&
47
+ clientOperatingStrategy(operatingMode ?? 'prod').supportsStatusBadge() &&
48
+ presentation
49
+ ? {
50
+ label: presentation.label,
51
+ value: branchIsProtected ? 'protected' : String(branchStatus),
52
+ testId: `header-status-badge-${branchIsProtected ? 'protected' : branchStatus}`,
53
+ }
54
+ : undefined;
55
+ return (_jsx(TopBar, { leading: _jsx(EntryBreadcrumb, { segments: breadcrumbSegments, entryLabel: currentEntry ? (currentEntry.label ?? currentEntry.slug) : undefined, entryDirty: hasUnsavedChanges, readOnlyReason: branchLoading
56
+ ? undefined
57
+ : currentEntry || branchName
58
+ ? (branchLockReason ?? entryLockReason)
59
+ : undefined, onAllContent: onNavigatorOpen, onCollection: onCollectionOpen, onRefresh: onFileReload, onDiscard: onFileDiscardDraft,
60
+ // A path rule's refusal hides them, as the content tree hides that entry's "…" menu.
61
+ onRename: entryReadOnly ? undefined : onEntryRename, onDelete: entryReadOnly ? undefined : onEntryDelete, refreshBlockedReason: branchName ? undefined : 'Open a branch first.', discardBlockedReason: entryHasDraft ? undefined : 'This entry has no unsaved changes.', changeBlockedReason: branchLockReason ??
62
+ (entryUnavailable
63
+ ? "This entry's content type isn't known to this editor version yet. Reload in a few minutes."
64
+ : undefined), entryMenuRef: navigatorToggleRef, allContentRef: allContentRef }), trailing: _jsxs(_Fragment, { children: [_jsx(BranchPill, { branchName: branchName, loading: busy, status: status, unsavedCount: modifiedCount, unsavedEntries: editedFiles, onSwitchBranch: onBranchManagerOpen, onRefreshBranch: onBranchReloadData, onDiscardAll: onBranchDiscardDrafts, onEntrySelect: onEntrySelect, pillRef: branchToggleRef }), _jsx(WorkflowButton, { branchName: branchName, busy: busy, branchStatus: branchStatus, userContext: userContext, branchCreatedBy: branchCreatedBy, branchAccess: branchAccess, branchIsProtected: branchIsProtected, onSubmit: onSubmit, onWithdraw: onWithdraw, savingAll: !!saveAllProgress }), _jsx(SaveSplitButton, { onSave: onSave, saveBlockedReason: saveBlockedReason, busy: busy, onSaveAll: onSaveAll, unsavedCount: modifiedCount, saveAllBlockedReason: branchLockReason ??
65
+ (!branchName
66
+ ? 'Open a branch first.'
67
+ : entryListFailed && modifiedCount > 0
68
+ ? 'The list of entries couldn\'t be loaded, so these changes can\'t be saved yet. Choose "Refresh branch" in the branch menu to try again.'
69
+ : undefined), saveAllProgress: saveAllProgress, saving: saving, savedSignal: savedSignal, savedHere: savedHere, entryDirty: hasUnsavedChanges, draftStorageFailed: draftStorageFailed })] }) }));
70
+ }
71
+ /** Submit for review, or Withdraw from review once submitted or approved. */
72
+ function WorkflowButton({ branchName, busy, branchStatus, userContext, branchCreatedBy, branchAccess, branchIsProtected, onSubmit, onWithdraw, savingAll, }) {
73
+ const isSubmitted = branchStatus === 'submitted';
74
+ const isEditing = branchStatus === 'editing';
75
+ // 'approved' withdraws too -- it is that status's only
76
+ // non-destructive exit now that the submit status gate refuses a
77
+ // non-editing branch (api/branch-status.ts, api/branch-withdraw.ts).
78
+ // This button is a two-state toggle, so every withdrawable status
79
+ // has to drive the withdraw side of it, not just 'submitted'.
80
+ const isWithdrawable = isSubmitted || branchStatus === 'approved';
81
+ // The protected base branch can never be submitted for review (both
82
+ // modes); hide the button entirely rather than showing it disabled.
83
+ // Withdraw stays available as the recovery path for a base branch
84
+ // wrongly stuck in 'submitted'.
85
+ if (branchIsProtected && !isWithdrawable)
86
+ return null;
87
+ // Who may submit/withdraw: creator, ACL access, the system branch, or an
88
+ // admin/reviewer (alone on a locked-down branch, and even without ACL access
89
+ // on a protected base branch stuck in 'submitted'). Mirrors the server's
90
+ // canPerformWorkflowAction (BranchManager.tsx), which is the actual
91
+ // enforcer; this only decides whether to show the control disabled.
92
+ const userIsCreator = userContext?.userId === branchCreatedBy;
93
+ const isSystemBranch = branchCreatedBy === SYSTEM_USER_ID && !branchIsProtected;
94
+ const userInACL = userContext &&
95
+ branchAccess &&
96
+ (branchAccess.allowedUsers?.includes(userContext.userId) ||
97
+ userContext.groups?.some((g) => branchAccess.allowedGroups?.includes(g)));
98
+ const userIsPrivileged = !!userContext && (isAdmin(userContext.groups ?? []) || isReviewer(userContext.groups ?? []));
99
+ const userHasPermission = !isLockedOutOfBranch(branchAccess, userContext?.groups) &&
100
+ (userIsCreator || userInACL || isSystemBranch || userIsPrivileged);
101
+ // A status with no available transition (today: 'archived') is a
102
+ // separate condition from lacking permission, and conflating them
103
+ // sent people to an admin to fix a non-permissions problem.
104
+ const statusHasAction = isEditing || isWithdrawable;
105
+ const canPerformAction = userHasPermission && statusHasAction;
106
+ // Blocked, it stays focusable (`aria-disabled`), so its reason opens on focus.
107
+ // `busy` alone can't hold it: an entry load clears that shared flag mid-run.
108
+ const actionBlocked = !branchName || busy || savingAll || !canPerformAction;
109
+ const waitReason = savingAll ? 'Wait for Save all to finish.' : undefined;
110
+ return (_jsx(Tooltip, { label:
111
+ // No branch data (`branchStatus === undefined`) must not be
112
+ // interpolated raw into this label. Guarded explicitly here rather
113
+ // than left to the early return above, which hides this button
114
+ // today only as a side effect of `branchIsProtected`'s `?? true`
115
+ // default -- not a guarantee this arm stays unreachable.
116
+ waitReason ??
117
+ (branchStatus === undefined
118
+ ? 'Branch details could not be loaded. Use "Switch branch…" to retry.'
119
+ : !statusHasAction
120
+ ? `This branch is ${branchStatus}, so it can't be submitted for review or withdrawn from review.`
121
+ : !userHasPermission
122
+ ? 'You do not have permission to submit this branch for review or withdraw it from review. Ask an admin for access.'
123
+ : ''), disabled: canPerformAction && !waitReason, multiline: true, maw: 320, children: _jsx(Button, { size: "sm",
124
+ // Save is the top bar's one filled primary; the rest take their colour's light variant.
125
+ variant: "light", color: isWithdrawable ? 'orange' : undefined, style: { flexShrink: 0 }, onClick: () => {
126
+ if (actionBlocked)
127
+ return;
128
+ if (isWithdrawable)
129
+ onWithdraw();
130
+ else
131
+ onSubmit();
132
+ }, "data-disabled": actionBlocked ? true : undefined, "aria-disabled": actionBlocked ? true : undefined, "data-testid": isWithdrawable ? 'withdraw-button' : 'submit-button', children: isWithdrawable ? EDITOR_ACTIONS.withdrawFromReview : EDITOR_ACTIONS.submitForReview }) }));
133
+ }
@@ -0,0 +1,49 @@
1
+ import { type ReactElement, type Ref } from 'react';
2
+ import type { PaneArrangement } from '../shell/PaneLayout.js';
3
+ export interface EditorRailProps {
4
+ siteTitle: string;
5
+ /** Opens the site's first entry, which is also what the editor opens with no entry asked for. */
6
+ onHomeOpen: () => void;
7
+ contentPanelOpen: boolean;
8
+ /** The content panel's element id, for `aria-controls`. */
9
+ contentPanelId: string;
10
+ onContentToggle: () => void;
11
+ onQuickOpen: () => void;
12
+ /** The quick open shortcut as the platform writes it, such as "⌘P". */
13
+ quickOpenShortcut: string;
14
+ /** The same shortcut for `aria-keyshortcuts`, such as "Meta+P". */
15
+ quickOpenKeys: string;
16
+ branchesOpen: boolean;
17
+ onBranchesOpen: () => void;
18
+ /** Without it, the Comments button is not offered (no branch, or a mode without comments). */
19
+ onCommentsOpen?: () => void;
20
+ commentsOpen: boolean;
21
+ unresolvedCommentCount: number;
22
+ mediaLibraryOpen: boolean;
23
+ onMediaLibraryOpen: () => void;
24
+ mediaButtonRef?: Ref<HTMLButtonElement>;
25
+ layout: PaneArrangement;
26
+ onLayoutChange: (layout: PaneArrangement) => void;
27
+ /** The preview is maximized, so the layout has nothing to arrange. */
28
+ layoutBlocked?: boolean;
29
+ /** Admin-only, like the other two below: each Settings item renders only when given. */
30
+ onPermissionManagerOpen?: () => void;
31
+ onGroupManagerOpen?: () => void;
32
+ onSystemHealthOpen?: () => void;
33
+ /** Takes focus back when a panel opened from the Settings menu closes. */
34
+ settingsToggleRef?: Ref<HTMLButtonElement>;
35
+ /** The adopter's account control, such as Clerk's UserButton; replaces the default buttons. */
36
+ AccountComponent?: React.ComponentType;
37
+ onAccountClick?: () => void;
38
+ onLogoutClick?: () => void;
39
+ }
40
+ /**
41
+ * @internal Exported for tests. The Settings button and its menu of `items`; with none, no
42
+ * button, since a menu that opens empty offers nothing.
43
+ */
44
+ export declare function SettingsMenu({ items, toggleRef, }: {
45
+ items: readonly ReactElement[];
46
+ toggleRef?: Ref<HTMLButtonElement>;
47
+ }): import("react/jsx-runtime").JSX.Element | null;
48
+ /** The editor's activity rail: what `ActivityRail` lays out, wired to the editor's surfaces. */
49
+ export declare function EditorRail({ siteTitle, onHomeOpen, contentPanelOpen, contentPanelId, onContentToggle, onQuickOpen, quickOpenShortcut, quickOpenKeys, branchesOpen, onBranchesOpen, onCommentsOpen, commentsOpen, unresolvedCommentCount, mediaLibraryOpen, onMediaLibraryOpen, mediaButtonRef, layout, onLayoutChange, layoutBlocked, onPermissionManagerOpen, onGroupManagerOpen, onSystemHealthOpen, settingsToggleRef, AccountComponent, onAccountClick, onLogoutClick, }: EditorRailProps): import("react/jsx-runtime").JSX.Element;