canopycms 0.0.0 → 0.0.2

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 (467) hide show
  1. package/dist/auth/plugin.d.ts +8 -0
  2. package/dist/auth/plugin.d.ts.map +1 -1
  3. package/dist/build-mode.d.ts +15 -5
  4. package/dist/build-mode.d.ts.map +1 -1
  5. package/dist/build-mode.js +18 -8
  6. package/dist/build-mode.js.map +1 -1
  7. package/dist/cli/init.d.ts +2 -2
  8. package/dist/cli/init.d.ts.map +1 -1
  9. package/dist/cli/init.js +37 -36
  10. package/dist/cli/init.js.map +1 -1
  11. package/dist/cli/template-files/ai-config.ts.template +21 -0
  12. package/dist/cli/template-files/ai-route.ts.template +10 -0
  13. package/dist/cli/template-files/canopy.ts.template +24 -0
  14. package/dist/cli/templates.d.ts +5 -1
  15. package/dist/cli/templates.d.ts.map +1 -1
  16. package/dist/cli/templates.js +9 -2
  17. package/dist/cli/templates.js.map +1 -1
  18. package/dist/config/schemas/config.d.ts +4 -0
  19. package/dist/config/schemas/config.d.ts.map +1 -1
  20. package/dist/config/schemas/config.js +2 -0
  21. package/dist/config/schemas/config.js.map +1 -1
  22. package/dist/config/types.d.ts +5 -0
  23. package/dist/config/types.d.ts.map +1 -1
  24. package/dist/content-reader.js +2 -2
  25. package/dist/content-reader.js.map +1 -1
  26. package/dist/context.js +5 -5
  27. package/dist/context.js.map +1 -1
  28. package/dist/operating-mode/client-unsafe-strategy.d.ts.map +1 -1
  29. package/dist/operating-mode/client-unsafe-strategy.js +15 -18
  30. package/dist/operating-mode/client-unsafe-strategy.js.map +1 -1
  31. package/dist/operating-mode/types.d.ts +8 -0
  32. package/dist/operating-mode/types.d.ts.map +1 -1
  33. package/dist/server.d.ts +2 -0
  34. package/dist/server.d.ts.map +1 -1
  35. package/dist/server.js +2 -0
  36. package/dist/server.js.map +1 -1
  37. package/package.json +5 -4
  38. package/src/cli/init.ts +43 -38
  39. package/dist/__integration__/fixtures/content-seeds.d.ts +0 -43
  40. package/dist/__integration__/fixtures/content-seeds.d.ts.map +0 -1
  41. package/dist/__integration__/fixtures/content-seeds.js +0 -99
  42. package/dist/__integration__/fixtures/content-seeds.js.map +0 -1
  43. package/dist/__integration__/fixtures/schemas.d.ts +0 -12
  44. package/dist/__integration__/fixtures/schemas.d.ts.map +0 -1
  45. package/dist/__integration__/fixtures/schemas.js +0 -65
  46. package/dist/__integration__/fixtures/schemas.js.map +0 -1
  47. package/dist/__integration__/test-utils/api-client.d.ts +0 -123
  48. package/dist/__integration__/test-utils/api-client.d.ts.map +0 -1
  49. package/dist/__integration__/test-utils/api-client.js +0 -118
  50. package/dist/__integration__/test-utils/api-client.js.map +0 -1
  51. package/dist/__integration__/test-utils/multi-user.d.ts +0 -25
  52. package/dist/__integration__/test-utils/multi-user.d.ts.map +0 -1
  53. package/dist/__integration__/test-utils/multi-user.js +0 -105
  54. package/dist/__integration__/test-utils/multi-user.js.map +0 -1
  55. package/dist/__integration__/test-utils/test-workspace.d.ts +0 -25
  56. package/dist/__integration__/test-utils/test-workspace.d.ts.map +0 -1
  57. package/dist/__integration__/test-utils/test-workspace.js +0 -102
  58. package/dist/__integration__/test-utils/test-workspace.js.map +0 -1
  59. package/dist/editor/BranchManager.stories.d.ts +0 -8
  60. package/dist/editor/BranchManager.stories.d.ts.map +0 -1
  61. package/dist/editor/BranchManager.stories.js +0 -74
  62. package/dist/editor/BranchManager.stories.js.map +0 -1
  63. package/dist/editor/CanopyEditor.stories.d.ts +0 -7
  64. package/dist/editor/CanopyEditor.stories.d.ts.map +0 -1
  65. package/dist/editor/CanopyEditor.stories.js +0 -99
  66. package/dist/editor/CanopyEditor.stories.js.map +0 -1
  67. package/dist/editor/CommentsPanel.stories.d.ts +0 -10
  68. package/dist/editor/CommentsPanel.stories.d.ts.map +0 -1
  69. package/dist/editor/CommentsPanel.stories.js +0 -175
  70. package/dist/editor/CommentsPanel.stories.js.map +0 -1
  71. package/dist/editor/Editor.stories.d.ts +0 -7
  72. package/dist/editor/Editor.stories.d.ts.map +0 -1
  73. package/dist/editor/Editor.stories.js +0 -95
  74. package/dist/editor/Editor.stories.js.map +0 -1
  75. package/dist/editor/EditorPanes.stories.d.ts +0 -7
  76. package/dist/editor/EditorPanes.stories.d.ts.map +0 -1
  77. package/dist/editor/EditorPanes.stories.js +0 -116
  78. package/dist/editor/EditorPanes.stories.js.map +0 -1
  79. package/dist/editor/EntryNavigator.stories.d.ts +0 -8
  80. package/dist/editor/EntryNavigator.stories.d.ts.map +0 -1
  81. package/dist/editor/EntryNavigator.stories.js +0 -42
  82. package/dist/editor/EntryNavigator.stories.js.map +0 -1
  83. package/dist/editor/FormRenderer.stories.d.ts +0 -7
  84. package/dist/editor/FormRenderer.stories.d.ts.map +0 -1
  85. package/dist/editor/FormRenderer.stories.js +0 -115
  86. package/dist/editor/FormRenderer.stories.js.map +0 -1
  87. package/dist/editor/GroupManager.stories.d.ts +0 -19
  88. package/dist/editor/GroupManager.stories.d.ts.map +0 -1
  89. package/dist/editor/GroupManager.stories.js +0 -265
  90. package/dist/editor/GroupManager.stories.js.map +0 -1
  91. package/dist/editor/PermissionManager.stories.d.ts +0 -20
  92. package/dist/editor/PermissionManager.stories.d.ts.map +0 -1
  93. package/dist/editor/PermissionManager.stories.js +0 -506
  94. package/dist/editor/PermissionManager.stories.js.map +0 -1
  95. package/dist/editor/comments/FieldWrapper.stories.d.ts +0 -10
  96. package/dist/editor/comments/FieldWrapper.stories.d.ts.map +0 -1
  97. package/dist/editor/comments/FieldWrapper.stories.js +0 -173
  98. package/dist/editor/comments/FieldWrapper.stories.js.map +0 -1
  99. package/dist/editor/fields/BlockField.stories.d.ts +0 -7
  100. package/dist/editor/fields/BlockField.stories.d.ts.map +0 -1
  101. package/dist/editor/fields/BlockField.stories.js +0 -50
  102. package/dist/editor/fields/BlockField.stories.js.map +0 -1
  103. package/dist/editor/fields/fields.stories.d.ts +0 -8
  104. package/dist/editor/fields/fields.stories.d.ts.map +0 -1
  105. package/dist/editor/fields/fields.stories.js +0 -34
  106. package/dist/editor/fields/fields.stories.js.map +0 -1
  107. package/dist/test-utils/api-test-helpers.d.ts +0 -238
  108. package/dist/test-utils/api-test-helpers.d.ts.map +0 -1
  109. package/dist/test-utils/api-test-helpers.js +0 -347
  110. package/dist/test-utils/api-test-helpers.js.map +0 -1
  111. package/dist/test-utils/console-spy.d.ts +0 -56
  112. package/dist/test-utils/console-spy.d.ts.map +0 -1
  113. package/dist/test-utils/console-spy.js +0 -81
  114. package/dist/test-utils/console-spy.js.map +0 -1
  115. package/dist/test-utils/git-helpers.d.ts +0 -21
  116. package/dist/test-utils/git-helpers.d.ts.map +0 -1
  117. package/dist/test-utils/git-helpers.js +0 -23
  118. package/dist/test-utils/git-helpers.js.map +0 -1
  119. package/dist/test-utils/index.d.ts +0 -5
  120. package/dist/test-utils/index.d.ts.map +0 -1
  121. package/dist/test-utils/index.js +0 -4
  122. package/dist/test-utils/index.js.map +0 -1
  123. package/src/__integration__/errors/invalid-content.test.ts +0 -238
  124. package/src/__integration__/errors/permission-denied.test.ts +0 -220
  125. package/src/__integration__/fixtures/content-seeds.ts +0 -105
  126. package/src/__integration__/fixtures/schemas.ts +0 -67
  127. package/src/__integration__/initialization/prod-sim-init.test.ts +0 -139
  128. package/src/__integration__/permissions/path-permissions.test.ts +0 -314
  129. package/src/__integration__/permissions/role-permissions.test.ts +0 -354
  130. package/src/__integration__/permissions/settings-branch-isolation.test.ts +0 -317
  131. package/src/__integration__/settings/groups-api.test.ts +0 -403
  132. package/src/__integration__/test-utils/api-client.ts +0 -167
  133. package/src/__integration__/test-utils/multi-user.ts +0 -129
  134. package/src/__integration__/test-utils/test-workspace.ts +0 -130
  135. package/src/__integration__/user/user-context.test.ts +0 -174
  136. package/src/__integration__/validation/input-validation.test.ts +0 -166
  137. package/src/__integration__/workflows/api-editing-workflow.test.ts +0 -244
  138. package/src/__integration__/workflows/conflict-resolution.test.ts +0 -259
  139. package/src/__integration__/workflows/editing-workflow.test.ts +0 -205
  140. package/src/__integration__/workflows/review-workflow.test.ts +0 -260
  141. package/src/ai/__tests__/build.integration.test.ts +0 -224
  142. package/src/ai/__tests__/generate.integration.test.ts +0 -495
  143. package/src/ai/__tests__/handler.integration.test.ts +0 -212
  144. package/src/ai/__tests__/json-to-markdown.test.ts +0 -553
  145. package/src/ai/generate.ts +0 -410
  146. package/src/ai/handler.ts +0 -123
  147. package/src/ai/index.ts +0 -26
  148. package/src/ai/json-to-markdown.ts +0 -424
  149. package/src/ai/resolve-branch.ts +0 -34
  150. package/src/ai/types.ts +0 -160
  151. package/src/api/AGENTS.md +0 -81
  152. package/src/api/__test__/mock-client.ts +0 -404
  153. package/src/api/assets.test.ts +0 -140
  154. package/src/api/assets.ts +0 -154
  155. package/src/api/branch-merge.test.ts +0 -163
  156. package/src/api/branch-merge.ts +0 -113
  157. package/src/api/branch-review.test.ts +0 -297
  158. package/src/api/branch-review.ts +0 -136
  159. package/src/api/branch-status.test.ts +0 -85
  160. package/src/api/branch-status.ts +0 -153
  161. package/src/api/branch-withdraw.test.ts +0 -146
  162. package/src/api/branch-withdraw.ts +0 -81
  163. package/src/api/branch-workflow.integration.test.ts +0 -578
  164. package/src/api/branch.test.ts +0 -620
  165. package/src/api/branch.ts +0 -492
  166. package/src/api/client.test.ts +0 -349
  167. package/src/api/client.ts +0 -506
  168. package/src/api/comments.test.ts +0 -285
  169. package/src/api/comments.ts +0 -210
  170. package/src/api/content.test.ts +0 -345
  171. package/src/api/content.ts +0 -454
  172. package/src/api/entries.test.ts +0 -1339
  173. package/src/api/entries.ts +0 -650
  174. package/src/api/github-sync.ts +0 -144
  175. package/src/api/groups.test.ts +0 -1013
  176. package/src/api/groups.ts +0 -375
  177. package/src/api/guards.test.ts +0 -533
  178. package/src/api/guards.ts +0 -271
  179. package/src/api/index.ts +0 -87
  180. package/src/api/permissions.test.ts +0 -766
  181. package/src/api/permissions.ts +0 -334
  182. package/src/api/reference-options.ts +0 -118
  183. package/src/api/resolve-references.ts +0 -107
  184. package/src/api/route-builder.ts +0 -289
  185. package/src/api/schema.test.ts +0 -840
  186. package/src/api/schema.ts +0 -936
  187. package/src/api/security.test.ts +0 -233
  188. package/src/api/settings-helpers.ts +0 -84
  189. package/src/api/types.ts +0 -40
  190. package/src/api/user.test.ts +0 -127
  191. package/src/api/user.ts +0 -42
  192. package/src/api/validators.test.ts +0 -275
  193. package/src/api/validators.ts +0 -176
  194. package/src/asset-store.test.ts +0 -37
  195. package/src/asset-store.ts +0 -110
  196. package/src/auth/cache.ts +0 -7
  197. package/src/auth/caching-auth-plugin.test.ts +0 -154
  198. package/src/auth/caching-auth-plugin.ts +0 -109
  199. package/src/auth/context-helpers.ts +0 -75
  200. package/src/auth/file-based-auth-cache.test.ts +0 -257
  201. package/src/auth/file-based-auth-cache.ts +0 -279
  202. package/src/auth/index.ts +0 -12
  203. package/src/auth/plugin.ts +0 -51
  204. package/src/auth/types.ts +0 -38
  205. package/src/authorization/__tests__/branch.test.ts +0 -260
  206. package/src/authorization/__tests__/content.test.ts +0 -142
  207. package/src/authorization/__tests__/path.test.ts +0 -133
  208. package/src/authorization/__tests__/permissions-loader.test.ts +0 -200
  209. package/src/authorization/branch.ts +0 -94
  210. package/src/authorization/content.ts +0 -93
  211. package/src/authorization/groups/index.ts +0 -11
  212. package/src/authorization/groups/loader.ts +0 -127
  213. package/src/authorization/groups/schema.ts +0 -48
  214. package/src/authorization/helpers.ts +0 -48
  215. package/src/authorization/index.ts +0 -84
  216. package/src/authorization/path.ts +0 -112
  217. package/src/authorization/permissions/index.ts +0 -11
  218. package/src/authorization/permissions/loader.ts +0 -116
  219. package/src/authorization/permissions/schema.ts +0 -66
  220. package/src/authorization/test-utils.ts +0 -15
  221. package/src/authorization/types.ts +0 -66
  222. package/src/authorization/validation.test.ts +0 -100
  223. package/src/authorization/validation.ts +0 -62
  224. package/src/branch-metadata.test.ts +0 -168
  225. package/src/branch-metadata.ts +0 -166
  226. package/src/branch-registry.test.ts +0 -248
  227. package/src/branch-registry.ts +0 -152
  228. package/src/branch-schema-cache.test.ts +0 -275
  229. package/src/branch-schema-cache.ts +0 -189
  230. package/src/branch-workspace.test.ts +0 -183
  231. package/src/branch-workspace.ts +0 -124
  232. package/src/build/generate-ai-content.ts +0 -78
  233. package/src/build/index.ts +0 -8
  234. package/src/build-mode.ts +0 -27
  235. package/src/cli/generate-ai-content.ts +0 -100
  236. package/src/cli/init.test.ts +0 -240
  237. package/src/cli/templates/canopy.ts.template +0 -55
  238. package/src/cli/templates.ts +0 -47
  239. package/src/client.ts +0 -12
  240. package/src/comment-store.test.ts +0 -442
  241. package/src/comment-store.ts +0 -301
  242. package/src/config/__tests__/config.test.ts +0 -513
  243. package/src/config/flatten.ts +0 -174
  244. package/src/config/helpers.ts +0 -167
  245. package/src/config/index.ts +0 -86
  246. package/src/config/schemas/collection.ts +0 -67
  247. package/src/config/schemas/config.ts +0 -77
  248. package/src/config/schemas/field.ts +0 -108
  249. package/src/config/schemas/media.ts +0 -27
  250. package/src/config/schemas/permissions.ts +0 -21
  251. package/src/config/types.ts +0 -321
  252. package/src/config/validation.ts +0 -70
  253. package/src/config-test.ts +0 -65
  254. package/src/config.ts +0 -11
  255. package/src/content-id-index.test.ts +0 -512
  256. package/src/content-id-index.ts +0 -479
  257. package/src/content-reader.test.ts +0 -478
  258. package/src/content-reader.ts +0 -214
  259. package/src/content-store.test.ts +0 -1126
  260. package/src/content-store.ts +0 -793
  261. package/src/context.ts +0 -111
  262. package/src/editor/BranchManager.stories.tsx +0 -80
  263. package/src/editor/BranchManager.test.tsx +0 -324
  264. package/src/editor/BranchManager.tsx +0 -461
  265. package/src/editor/CanopyEditor.stories.tsx +0 -128
  266. package/src/editor/CanopyEditor.test.tsx +0 -81
  267. package/src/editor/CanopyEditor.tsx +0 -73
  268. package/src/editor/CanopyEditorPage.test.tsx +0 -59
  269. package/src/editor/CanopyEditorPage.tsx +0 -25
  270. package/src/editor/CommentsPanel.stories.tsx +0 -184
  271. package/src/editor/CommentsPanel.tsx +0 -338
  272. package/src/editor/Editor.integration.test.tsx +0 -227
  273. package/src/editor/Editor.stories.tsx +0 -119
  274. package/src/editor/Editor.tsx +0 -1221
  275. package/src/editor/EditorPanes.stories.tsx +0 -256
  276. package/src/editor/EditorPanes.test.tsx +0 -77
  277. package/src/editor/EditorPanes.tsx +0 -180
  278. package/src/editor/EntryNavigator.stories.tsx +0 -65
  279. package/src/editor/EntryNavigator.test.tsx +0 -598
  280. package/src/editor/EntryNavigator.tsx +0 -665
  281. package/src/editor/FormRenderer.stories.tsx +0 -212
  282. package/src/editor/FormRenderer.test.tsx +0 -194
  283. package/src/editor/FormRenderer.tsx +0 -432
  284. package/src/editor/GroupManager.stories.tsx +0 -301
  285. package/src/editor/GroupManager.test.tsx +0 -682
  286. package/src/editor/GroupManager.tsx +0 -9
  287. package/src/editor/PermissionManager.stories.tsx +0 -539
  288. package/src/editor/PermissionManager.test.tsx +0 -864
  289. package/src/editor/PermissionManager.tsx +0 -12
  290. package/src/editor/canopy-path.test.ts +0 -23
  291. package/src/editor/canopy-path.ts +0 -52
  292. package/src/editor/client-reference-resolver.ts +0 -118
  293. package/src/editor/comments/BranchComments.tsx +0 -93
  294. package/src/editor/comments/EntryComments.tsx +0 -94
  295. package/src/editor/comments/FieldWrapper.stories.tsx +0 -210
  296. package/src/editor/comments/FieldWrapper.tsx +0 -129
  297. package/src/editor/comments/InlineCommentThread.test.tsx +0 -384
  298. package/src/editor/comments/InlineCommentThread.tsx +0 -246
  299. package/src/editor/comments/ThreadCarousel.test.tsx +0 -393
  300. package/src/editor/comments/ThreadCarousel.tsx +0 -525
  301. package/src/editor/components/ConfirmDeleteModal.tsx +0 -49
  302. package/src/editor/components/EditorContext.tsx +0 -49
  303. package/src/editor/components/EditorFooter.tsx +0 -47
  304. package/src/editor/components/EditorHeader.tsx +0 -492
  305. package/src/editor/components/EditorSidebar.tsx +0 -193
  306. package/src/editor/components/EntryCreateModal.tsx +0 -193
  307. package/src/editor/components/RenameEntryModal.tsx +0 -152
  308. package/src/editor/components/UserBadge.test.tsx +0 -274
  309. package/src/editor/components/UserBadge.tsx +0 -240
  310. package/src/editor/components/index.ts +0 -6
  311. package/src/editor/context/ApiClientContext.tsx +0 -56
  312. package/src/editor/context/EditorStateContext.tsx +0 -221
  313. package/src/editor/context/index.ts +0 -40
  314. package/src/editor/editor-config.test.ts +0 -385
  315. package/src/editor/editor-config.ts +0 -94
  316. package/src/editor/editor-utils.test.ts +0 -772
  317. package/src/editor/editor-utils.ts +0 -303
  318. package/src/editor/env.ts +0 -4
  319. package/src/editor/fields/BlockField.stories.tsx +0 -79
  320. package/src/editor/fields/BlockField.tsx +0 -267
  321. package/src/editor/fields/CodeField.tsx +0 -41
  322. package/src/editor/fields/MarkdownField.tsx +0 -205
  323. package/src/editor/fields/ObjectField.tsx +0 -71
  324. package/src/editor/fields/ReferenceField.tsx +0 -138
  325. package/src/editor/fields/SelectField.tsx +0 -76
  326. package/src/editor/fields/TextField.tsx +0 -35
  327. package/src/editor/fields/ToggleField.tsx +0 -37
  328. package/src/editor/fields/fields.stories.tsx +0 -40
  329. package/src/editor/group-manager/ExternalGroupsTab.tsx +0 -114
  330. package/src/editor/group-manager/GroupCard.tsx +0 -102
  331. package/src/editor/group-manager/GroupForm.tsx +0 -66
  332. package/src/editor/group-manager/InternalGroupsTab.tsx +0 -147
  333. package/src/editor/group-manager/MemberList.tsx +0 -184
  334. package/src/editor/group-manager/hooks/useExternalGroupSearch.ts +0 -63
  335. package/src/editor/group-manager/hooks/useGroupState.ts +0 -134
  336. package/src/editor/group-manager/hooks/useUserSearch.ts +0 -84
  337. package/src/editor/group-manager/index.tsx +0 -210
  338. package/src/editor/group-manager/types.ts +0 -28
  339. package/src/editor/hooks/README.md +0 -26
  340. package/src/editor/hooks/__test__/test-utils.tsx +0 -183
  341. package/src/editor/hooks/index.ts +0 -23
  342. package/src/editor/hooks/useBranchActions.test.tsx +0 -267
  343. package/src/editor/hooks/useBranchActions.tsx +0 -121
  344. package/src/editor/hooks/useBranchManager.test.tsx +0 -391
  345. package/src/editor/hooks/useBranchManager.tsx +0 -326
  346. package/src/editor/hooks/useCommentSystem.test.ts +0 -615
  347. package/src/editor/hooks/useCommentSystem.ts +0 -347
  348. package/src/editor/hooks/useDraftManager.test.ts +0 -375
  349. package/src/editor/hooks/useDraftManager.ts +0 -259
  350. package/src/editor/hooks/useEditorLayout.test.ts +0 -147
  351. package/src/editor/hooks/useEditorLayout.ts +0 -67
  352. package/src/editor/hooks/useEntryManager.test.ts +0 -588
  353. package/src/editor/hooks/useEntryManager.ts +0 -387
  354. package/src/editor/hooks/useGroupManager.test.ts +0 -277
  355. package/src/editor/hooks/useGroupManager.ts +0 -139
  356. package/src/editor/hooks/usePermissionManager.test.ts +0 -211
  357. package/src/editor/hooks/usePermissionManager.ts +0 -113
  358. package/src/editor/hooks/useReferenceResolution.ts +0 -248
  359. package/src/editor/hooks/useSchemaManager.test.ts +0 -370
  360. package/src/editor/hooks/useSchemaManager.ts +0 -310
  361. package/src/editor/hooks/useUserContext.tsx +0 -57
  362. package/src/editor/hooks/useUserMetadata.test.ts +0 -191
  363. package/src/editor/hooks/useUserMetadata.ts +0 -71
  364. package/src/editor/permission-manager/GroupSelector.tsx +0 -73
  365. package/src/editor/permission-manager/PermissionEditor.tsx +0 -321
  366. package/src/editor/permission-manager/PermissionLevelBadge.tsx +0 -53
  367. package/src/editor/permission-manager/PermissionTree.tsx +0 -237
  368. package/src/editor/permission-manager/UserSelector.tsx +0 -95
  369. package/src/editor/permission-manager/constants.tsx +0 -18
  370. package/src/editor/permission-manager/hooks/useGroupsAndUsers.ts +0 -153
  371. package/src/editor/permission-manager/hooks/usePermissionTree.ts +0 -200
  372. package/src/editor/permission-manager/index.tsx +0 -294
  373. package/src/editor/permission-manager/types.ts +0 -58
  374. package/src/editor/permission-manager/utils.ts +0 -179
  375. package/src/editor/preview-bridge.test.tsx +0 -50
  376. package/src/editor/preview-bridge.tsx +0 -294
  377. package/src/editor/schema-editor/CollectionEditor.test.tsx +0 -238
  378. package/src/editor/schema-editor/CollectionEditor.tsx +0 -520
  379. package/src/editor/schema-editor/EntryTypeEditor.test.tsx +0 -215
  380. package/src/editor/schema-editor/EntryTypeEditor.tsx +0 -367
  381. package/src/editor/schema-editor/index.ts +0 -19
  382. package/src/editor/setup-test-dom.ts +0 -10
  383. package/src/editor/test-setup.ts +0 -33
  384. package/src/editor/theme.tsx +0 -119
  385. package/src/editor/utils/env.ts +0 -39
  386. package/src/entry-schema-registry.test.ts +0 -281
  387. package/src/entry-schema-registry.ts +0 -121
  388. package/src/entry-schema.ts +0 -84
  389. package/src/git-manager.test.ts +0 -552
  390. package/src/git-manager.ts +0 -667
  391. package/src/github-service.test.ts +0 -312
  392. package/src/github-service.ts +0 -295
  393. package/src/http/handler.test.ts +0 -275
  394. package/src/http/handler.ts +0 -280
  395. package/src/http/index.ts +0 -11
  396. package/src/http/router.ts +0 -164
  397. package/src/http/types.ts +0 -44
  398. package/src/id.test.ts +0 -48
  399. package/src/id.ts +0 -22
  400. package/src/index.ts +0 -26
  401. package/src/operating-mode/__tests__/strategies.test.ts +0 -511
  402. package/src/operating-mode/client-safe-strategy.ts +0 -184
  403. package/src/operating-mode/client-unsafe-strategy.ts +0 -303
  404. package/src/operating-mode/client.ts +0 -13
  405. package/src/operating-mode/index.ts +0 -34
  406. package/src/operating-mode/types.ts +0 -186
  407. package/src/paths/__tests__/branch.test.ts +0 -53
  408. package/src/paths/__tests__/normalize.test.ts +0 -141
  409. package/src/paths/__tests__/resolve.test.ts +0 -207
  410. package/src/paths/__tests__/validation.test.ts +0 -61
  411. package/src/paths/branch.ts +0 -115
  412. package/src/paths/index.ts +0 -73
  413. package/src/paths/normalize-server.ts +0 -40
  414. package/src/paths/normalize.ts +0 -107
  415. package/src/paths/resolve.ts +0 -61
  416. package/src/paths/test-utils.ts +0 -37
  417. package/src/paths/types.ts +0 -68
  418. package/src/paths/validation.test.ts +0 -480
  419. package/src/paths/validation.ts +0 -391
  420. package/src/reference-resolver.test.ts +0 -107
  421. package/src/reference-resolver.ts +0 -157
  422. package/src/schema/index.ts +0 -29
  423. package/src/schema/meta-loader.ts +0 -366
  424. package/src/schema/resolver.ts +0 -83
  425. package/src/schema/schema-store-types.ts +0 -56
  426. package/src/schema/schema-store.test.ts +0 -816
  427. package/src/schema/schema-store.ts +0 -795
  428. package/src/schema/types.ts +0 -33
  429. package/src/schema-meta-loader.test.ts +0 -447
  430. package/src/server.ts +0 -15
  431. package/src/services.test.ts +0 -559
  432. package/src/services.ts +0 -373
  433. package/src/settings-branch-utils.ts +0 -53
  434. package/src/settings-workspace.ts +0 -156
  435. package/src/task-queue/README.md +0 -144
  436. package/src/task-queue/index.ts +0 -14
  437. package/src/task-queue/task-queue.test.ts +0 -524
  438. package/src/task-queue/task-queue.ts +0 -514
  439. package/src/task-queue/types.ts +0 -41
  440. package/src/test-utils/api-test-helpers.ts +0 -445
  441. package/src/test-utils/console-spy.test.ts +0 -14
  442. package/src/test-utils/console-spy.ts +0 -125
  443. package/src/test-utils/git-helpers.ts +0 -31
  444. package/src/test-utils/index.ts +0 -4
  445. package/src/types.ts +0 -54
  446. package/src/user.ts +0 -118
  447. package/src/utils/debug.test.ts +0 -114
  448. package/src/utils/debug.ts +0 -127
  449. package/src/utils/error.test.ts +0 -92
  450. package/src/utils/error.ts +0 -83
  451. package/src/utils/format.ts +0 -12
  452. package/src/validation/__tests__/field-traversal.test.ts +0 -263
  453. package/src/validation/deletion-checker.ts +0 -234
  454. package/src/validation/field-traversal.ts +0 -146
  455. package/src/validation/reference-validator.ts +0 -168
  456. package/src/worker/cms-worker-rebase.test.ts +0 -473
  457. package/src/worker/cms-worker.ts +0 -777
  458. package/src/worker/integration.test.ts +0 -289
  459. package/src/worker/task-queue-config.ts +0 -25
  460. package/src/worker/task-queue.test.ts +0 -452
  461. package/src/worker/task-queue.ts +0 -58
  462. /package/{src/cli/templates → dist/cli/template-files}/Dockerfile.cms.template +0 -0
  463. /package/{src/cli/templates → dist/cli/template-files}/canopycms.config.ts.template +0 -0
  464. /package/{src/cli/templates → dist/cli/template-files}/deploy-cms.yml.template +0 -0
  465. /package/{src/cli/templates → dist/cli/template-files}/edit-page.tsx.template +0 -0
  466. /package/{src/cli/templates → dist/cli/template-files}/route.ts.template +0 -0
  467. /package/{src/cli/templates → dist/cli/template-files}/schemas.ts.template +0 -0
@@ -1,525 +0,0 @@
1
- 'use client'
2
-
3
- import React, { useState, useMemo, useEffect, useRef } from 'react'
4
- import { ActionIcon, Alert, Button, Group, Paper, Stack, Text, Textarea } from '@mantine/core'
5
- import { IconChevronLeft, IconChevronRight, IconAlertCircle } from '@tabler/icons-react'
6
- import type { CommentThread } from '../../comment-store'
7
- import type { UserSearchResult } from '../../auth/types'
8
- import { InlineCommentThread } from './InlineCommentThread'
9
-
10
- /**
11
- * ThreadCarousel - Horizontal comment thread navigation component
12
- *
13
- * ## Purpose
14
- * Provides a horizontal carousel UI for navigating between multiple comment threads
15
- * on fields, entries, or branches. Supports both keyboard navigation (arrow buttons)
16
- * and displays a visual "peekaboo" preview of adjacent threads.
17
- *
18
- * ## Key Behaviors
19
- *
20
- * ### Layout & Sizing
21
- * - **Active thread width**: `calc(100% - 72px)` - fills container minus peekaboo space
22
- * - **Single thread width**: `calc(100% - 72px)` - same as active (for consistency)
23
- * - **Inactive thread width**: `400px` - fixed width when not in view
24
- * - **Peekaboo size**: `60px` - sliver of next thread shown on right edge
25
- * - **Gap between threads**: `12px`
26
- *
27
- * ### Peekaboo Preview
28
- * - Shows 60px of the next thread on the right edge (when not viewing last thread)
29
- * - Gradient fade overlay applied to peekaboo area for visual polish
30
- * - **Last thread behavior**: Invisible 60px spacer ensures last thread stays left-aligned
31
- * without showing previous threads on the left
32
- * - Peekaboo helps users discover there are more threads to navigate
33
- *
34
- * ### Thread Sorting
35
- * - **Unresolved threads first** (primary sort)
36
- * - **Newest first within same resolved state** (secondary sort by createdAt)
37
- * - This ensures urgent unresolved feedback appears first
38
- *
39
- * ### Navigation
40
- * - **Arrow buttons**: `← 2/5 →` counter with disabled states at boundaries
41
- * - **Smooth scrolling**: CSS `scroll-behavior: smooth` with programmatic scroll
42
- * - **Auto-scroll**: When `autoFocus` is true, automatically scrolls to first unresolved thread
43
- * - **Mouse scrolling disabled**: `overflowX: 'hidden'` - only button navigation allowed
44
- * - **Scroll calculation**: Accounts for active thread width + gaps when navigating
45
- *
46
- * ### Always-Visible Design
47
- * - Component renders even with 0 threads (shows "No comments yet" message)
48
- * - "New" button always accessible in header
49
- * - Header shows thread count when threads exist: "Comments (3)"
50
- * - Navigation arrows only appear when multiple threads exist
51
- *
52
- * ### Vertical Resizing
53
- * - **Default height**: 400px
54
- * - **Resize range**: 200px (min) to 600px (max)
55
- * - **Resize handle**: Bottom edge with visual feedback on hover/drag
56
- * - User can drag to adjust carousel height for their workflow
57
- *
58
- * ### New Thread Creation
59
- * - "New" button in header toggles inline thread creation box
60
- * - `autoOpenNewThread` prop auto-opens box (used when clicking "New comment" button)
61
- * - New thread box appears above carousel, with textarea and Create/Cancel buttons
62
- *
63
- * ## Usage Context
64
- * Used by:
65
- * - **FieldWrapper**: Inline comments beneath form fields
66
- * - **EntryComments**: Comments at top of entry form
67
- * - **BranchComments**: Comments at top of BranchManager
68
- *
69
- * ## Design Decisions
70
- *
71
- * ### Why calc(100% - 72px)?
72
- * - 60px for peekaboo preview + 12px gap = 72px total
73
- * - Active thread fills remaining space for maximum readability
74
- * - Consistent sizing between single thread and active thread in multi-thread scenarios
75
- *
76
- * ### Why invisible spacer at end?
77
- * - Without spacer: last thread would align to right edge, showing previous threads on left
78
- * - With spacer: last thread stays left-aligned with blank space on right (matching peekaboo size)
79
- * - Creates consistent left-alignment across all thread positions
80
- *
81
- * ### Why disable mouse scrolling?
82
- * - Prevents accidental scroll-wheel navigation that could be jarring
83
- * - Forces deliberate button-based navigation for better UX
84
- * - Scroll-snap still works programmatically for smooth transitions
85
- *
86
- * ### Why sort unresolved first?
87
- * - Unresolved threads require action, so they should be most visible
88
- * - Resolved threads are less urgent and can appear later in carousel
89
- * - Newest-first secondary sort ensures recent feedback is prioritized
90
- */
91
-
92
- export interface ThreadCarouselProps {
93
- /** All threads for this context */
94
- threads: CommentThread[]
95
- /** Label for the comment section (e.g., "Comments", "Entry Comments") */
96
- label?: string
97
- /** Context type for creating new threads */
98
- contextType: 'field' | 'entry' | 'branch'
99
- /** Current user ID */
100
- currentUserId: string
101
- /** Whether user can resolve threads */
102
- canResolve: boolean
103
- /** Handler to add a new comment (creates new thread or adds to existing) */
104
- onAddComment: (text: string, threadId?: string) => Promise<void>
105
- /** Handler to resolve a thread */
106
- onResolveThread: (threadId: string) => Promise<void>
107
- /** Auto-focus and expand (from preview click) */
108
- autoFocus?: boolean
109
- /** Auto-open new thread box */
110
- autoOpenNewThread?: boolean
111
- /** Thread ID to highlight and scroll to */
112
- highlightThreadId?: string
113
- /** Optional function to fetch user metadata for displaying user badges */
114
- onGetUserMetadata?: (userId: string) => Promise<UserSearchResult | null>
115
- }
116
- export const ThreadCarousel: React.FC<ThreadCarouselProps> = ({
117
- threads,
118
- label = 'Comments',
119
- contextType: _,
120
- currentUserId,
121
- canResolve,
122
- onAddComment,
123
- onResolveThread,
124
- autoFocus,
125
- autoOpenNewThread,
126
- highlightThreadId,
127
- onGetUserMetadata,
128
- }) => {
129
- const [currentIndex, setCurrentIndex] = useState(0)
130
- const [showNewThreadBox, setShowNewThreadBox] = useState(false)
131
- const [newThreadText, setNewThreadText] = useState('')
132
- const [isSubmitting, setIsSubmitting] = useState(false)
133
- const [carouselHeight, setCarouselHeight] = useState(400)
134
- const [isResizing, setIsResizing] = useState(false)
135
- const [highlightedThreadId, setHighlightedThreadId] = useState<string | undefined>(undefined)
136
- const [error, setError] = useState<string | null>(null)
137
- const scrollContainerRef = useRef<HTMLDivElement>(null)
138
- const resizeStartY = useRef<number>(0)
139
- const resizeStartHeight = useRef<number>(0)
140
-
141
- // Sort: unresolved first, then resolved
142
- const sortedThreads = useMemo(
143
- () =>
144
- [...threads].sort((a, b) => {
145
- if (a.resolved === b.resolved) {
146
- // Same resolved state: sort by createdAt (newest first)
147
- return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
148
- }
149
- return a.resolved ? 1 : -1
150
- }),
151
- [threads],
152
- )
153
-
154
- // Auto-scroll to first unresolved thread when autoFocus is true
155
-
156
- useEffect(() => {
157
- if (autoFocus && sortedThreads.length > 0) {
158
- const firstUnresolved = sortedThreads.find((t) => !t.resolved)
159
- if (firstUnresolved) {
160
- const index = sortedThreads.findIndex((t) => t.id === firstUnresolved.id)
161
- setCurrentIndex(index)
162
- // Scroll to thread
163
- scrollToIndex(index)
164
- }
165
- }
166
- // eslint-disable-next-line react-hooks/exhaustive-deps -- scrollToIndex is stable
167
- }, [autoFocus, sortedThreads])
168
-
169
- // Scroll to and highlight specific thread when highlightThreadId changes
170
-
171
- useEffect(() => {
172
- if (highlightThreadId && sortedThreads.length > 0) {
173
- const threadIndex = sortedThreads.findIndex((t) => t.id === highlightThreadId)
174
- if (threadIndex !== -1) {
175
- setCurrentIndex(threadIndex)
176
- scrollToIndex(threadIndex)
177
- setHighlightedThreadId(highlightThreadId)
178
- // Clear highlight after 2 seconds
179
- const timer = window.setTimeout(() => {
180
- setHighlightedThreadId(undefined)
181
- }, 2000)
182
- return () => window.clearTimeout(timer)
183
- }
184
- }
185
- // eslint-disable-next-line react-hooks/exhaustive-deps -- scrollToIndex is stable
186
- }, [highlightThreadId, sortedThreads])
187
-
188
- // Auto-open new thread box when autoOpenNewThread is true
189
- useEffect(() => {
190
- if (autoOpenNewThread) {
191
- setShowNewThreadBox(true)
192
- }
193
- }, [autoOpenNewThread])
194
-
195
- // Handle resize dragging
196
- useEffect(() => {
197
- const handleMouseMove = (e: MouseEvent) => {
198
- if (!isResizing) return
199
- const delta = e.clientY - resizeStartY.current
200
- const newHeight = Math.max(200, Math.min(600, resizeStartHeight.current + delta))
201
- setCarouselHeight(newHeight)
202
- }
203
-
204
- const handleMouseUp = () => {
205
- setIsResizing(false)
206
- }
207
-
208
- if (isResizing) {
209
- document.addEventListener('mousemove', handleMouseMove)
210
- document.addEventListener('mouseup', handleMouseUp)
211
- return () => {
212
- document.removeEventListener('mousemove', handleMouseMove)
213
- document.removeEventListener('mouseup', handleMouseUp)
214
- }
215
- }
216
- }, [isResizing])
217
-
218
- const handleResizeStart = (e: React.MouseEvent) => {
219
- e.preventDefault()
220
- setIsResizing(true)
221
- resizeStartY.current = e.clientY
222
- resizeStartHeight.current = carouselHeight
223
- }
224
-
225
- const scrollToIndex = (index: number) => {
226
- if (scrollContainerRef.current) {
227
- const container = scrollContainerRef.current
228
- // Calculate scroll position based on container width
229
- // Active thread takes most space, others are 400px + gap
230
- let scrollLeft = 0
231
- for (let i = 0; i < index; i++) {
232
- if (sortedThreads.length > 1) {
233
- // Each previous thread was the active one when visible, so use full width
234
- scrollLeft += container.clientWidth - 72 + 12 // width - peekaboo + gap
235
- } else {
236
- scrollLeft += 400 + 12
237
- }
238
- }
239
- container.scrollTo({
240
- left: scrollLeft,
241
- behavior: 'smooth',
242
- })
243
- }
244
- }
245
-
246
- const handlePrevious = () => {
247
- if (currentIndex > 0) {
248
- const newIndex = currentIndex - 1
249
- setCurrentIndex(newIndex)
250
- scrollToIndex(newIndex)
251
- }
252
- }
253
-
254
- const handleNext = () => {
255
- if (currentIndex < sortedThreads.length - 1) {
256
- const newIndex = currentIndex + 1
257
- setCurrentIndex(newIndex)
258
- scrollToIndex(newIndex)
259
- }
260
- }
261
-
262
- const handleAddReply = async (threadId: string, text: string) => {
263
- try {
264
- setError(null)
265
- await onAddComment(text, threadId)
266
- } catch (err) {
267
- setError(err instanceof Error ? err.message : 'Failed to add reply')
268
- throw err // Re-throw so InlineCommentThread can handle it
269
- }
270
- }
271
-
272
- const handleCreateNewThread = async () => {
273
- if (!newThreadText.trim()) return
274
-
275
- setIsSubmitting(true)
276
- setError(null)
277
- try {
278
- await onAddComment(newThreadText)
279
- setNewThreadText('')
280
- setShowNewThreadBox(false)
281
- } catch (err) {
282
- setError(err instanceof Error ? err.message : 'Failed to create comment')
283
- } finally {
284
- setIsSubmitting(false)
285
- }
286
- }
287
-
288
- const unresolvedCount = sortedThreads.filter((t) => !t.resolved).length
289
-
290
- return (
291
- <Paper p="sm" bg="gray.0" style={{ marginTop: 8 }}>
292
- <Stack gap="xs">
293
- {/* Header: always visible */}
294
- <Group justify="space-between" align="center">
295
- <Group gap="xs">
296
- <Text size="sm" fw={600}>
297
- {label}
298
- {sortedThreads.length > 0 && ` (${sortedThreads.length})`}
299
- </Text>
300
- {unresolvedCount > 0 && (
301
- <Text size="xs" c="orange" fw={600}>
302
- {unresolvedCount} unresolved
303
- </Text>
304
- )}
305
- </Group>
306
-
307
- <Group gap="xs">
308
- {/* Navigation arrows (only if multiple threads) */}
309
- {sortedThreads.length > 1 && (
310
- <>
311
- <ActionIcon
312
- size="sm"
313
- variant="subtle"
314
- onClick={handlePrevious}
315
- disabled={currentIndex === 0}
316
- >
317
- <IconChevronLeft size={16} />
318
- </ActionIcon>
319
- <Text size="xs" fw={500}>
320
- {currentIndex + 1}/{sortedThreads.length}
321
- </Text>
322
- <ActionIcon
323
- size="sm"
324
- variant="subtle"
325
- onClick={handleNext}
326
- disabled={currentIndex === sortedThreads.length - 1}
327
- >
328
- <IconChevronRight size={16} />
329
- </ActionIcon>
330
- <div
331
- style={{
332
- width: 1,
333
- height: 16,
334
- background: 'var(--mantine-color-gray-4)',
335
- }}
336
- />
337
- </>
338
- )}
339
-
340
- {/* New button (always visible) */}
341
- <Button
342
- size="xs"
343
- variant="light"
344
- onClick={() => setShowNewThreadBox(!showNewThreadBox)}
345
- >
346
- + New
347
- </Button>
348
- </Group>
349
- </Group>
350
-
351
- {/* Error display */}
352
- {error && (
353
- <Alert
354
- icon={<IconAlertCircle size={16} />}
355
- color="red"
356
- variant="light"
357
- onClose={() => setError(null)}
358
- withCloseButton
359
- >
360
- {error}
361
- </Alert>
362
- )}
363
-
364
- {/* New thread box */}
365
- {showNewThreadBox && (
366
- <Paper withBorder p="sm" bg="white">
367
- <Stack gap="xs">
368
- <Textarea
369
- placeholder="Start a new thread..."
370
- value={newThreadText}
371
- onChange={(e) => setNewThreadText(e.target.value)}
372
- minRows={2}
373
- disabled={isSubmitting}
374
- autoFocus
375
- data-testid="new-thread-textarea"
376
- />
377
- <Group gap="xs">
378
- <Button
379
- size="xs"
380
- onClick={handleCreateNewThread}
381
- loading={isSubmitting}
382
- disabled={!newThreadText.trim()}
383
- data-testid="create-thread-button"
384
- >
385
- Create Thread
386
- </Button>
387
- <Button size="xs" variant="subtle" onClick={() => setShowNewThreadBox(false)}>
388
- Cancel
389
- </Button>
390
- </Group>
391
- </Stack>
392
- </Paper>
393
- )}
394
-
395
- {/* Thread carousel */}
396
- {sortedThreads.length > 0 && (
397
- <div
398
- style={{
399
- position: 'relative',
400
- width: '100%',
401
- }}
402
- >
403
- <div
404
- ref={scrollContainerRef}
405
- style={{
406
- display: 'flex',
407
- gap: 12,
408
- overflowX: 'hidden', // Disable mouse scrolling
409
- scrollSnapType: 'x mandatory',
410
- scrollBehavior: 'smooth',
411
- maxHeight: carouselHeight,
412
- position: 'relative',
413
- width: '100%', // Ensure container respects parent width boundary
414
- }}
415
- >
416
- {sortedThreads.map((thread, idx) => {
417
- const isActive = idx === currentIndex
418
- const isHighlighted = thread.id === highlightedThreadId
419
-
420
- return (
421
- <div
422
- key={thread.id}
423
- style={{
424
- scrollSnapAlign: 'start',
425
- flexShrink: 0,
426
- // Active thread or single thread stretches to fill space minus peekaboo
427
- width:
428
- isActive || sortedThreads.length === 1
429
- ? 'calc(100% - 72px)' // Active or single: leave room for peekaboo/spacing
430
- : 400, // Non-active: fixed width
431
- maxWidth: isActive || sortedThreads.length === 1 ? 'calc(100% - 72px)' : 400,
432
- // Add highlight animation
433
- outline: isHighlighted ? '3px solid var(--mantine-color-blue-5)' : undefined,
434
- outlineOffset: isHighlighted ? 2 : undefined,
435
- borderRadius: isHighlighted ? 8 : undefined,
436
- transition: 'outline 0.3s ease, outline-offset 0.3s ease',
437
- }}
438
- >
439
- <InlineCommentThread
440
- thread={thread}
441
- onAddReply={(text) => handleAddReply(thread.id, text)}
442
- onResolve={() => onResolveThread(thread.id)}
443
- currentUserId={currentUserId}
444
- canResolve={canResolve}
445
- onGetUserMetadata={onGetUserMetadata}
446
- />
447
- </div>
448
- )
449
- })}
450
-
451
- {/* Invisible spacer at end to maintain left alignment for last thread */}
452
- {sortedThreads.length > 1 && (
453
- <div
454
- style={{
455
- flexShrink: 0,
456
- width: 60, // Match peekaboo size
457
- visibility: 'hidden',
458
- }}
459
- />
460
- )}
461
- </div>
462
-
463
- {/* Peekaboo gradient fade overlay */}
464
- {sortedThreads.length > 1 && currentIndex < sortedThreads.length - 1 && (
465
- <div
466
- style={{
467
- position: 'absolute',
468
- top: 0,
469
- right: 0,
470
- width: 60,
471
- height: '100%',
472
- background:
473
- 'linear-gradient(to left, var(--mantine-color-gray-0) 0%, transparent 100%)',
474
- pointerEvents: 'none',
475
- }}
476
- />
477
- )}
478
-
479
- {/* Resize handle */}
480
- <div
481
- onMouseDown={handleResizeStart}
482
- style={{
483
- position: 'absolute',
484
- bottom: 0,
485
- left: 0,
486
- right: 0,
487
- height: 8,
488
- cursor: 'ns-resize',
489
- background: isResizing ? 'var(--mantine-color-blue-5)' : 'transparent',
490
- transition: 'background 0.2s',
491
- display: 'flex',
492
- alignItems: 'center',
493
- justifyContent: 'center',
494
- }}
495
- onMouseEnter={(e) => {
496
- e.currentTarget.style.background = 'var(--mantine-color-gray-3)'
497
- }}
498
- onMouseLeave={(e) => {
499
- if (!isResizing) {
500
- e.currentTarget.style.background = 'transparent'
501
- }
502
- }}
503
- >
504
- <div
505
- style={{
506
- width: 40,
507
- height: 3,
508
- borderRadius: 2,
509
- background: 'var(--mantine-color-gray-5)',
510
- }}
511
- />
512
- </div>
513
- </div>
514
- )}
515
-
516
- {/* Empty state */}
517
- {sortedThreads.length === 0 && !showNewThreadBox && (
518
- <Text size="xs" c="dimmed" ta="center" py="xs">
519
- No comments yet. Click &quot;+ New&quot; to start a thread.
520
- </Text>
521
- )}
522
- </Stack>
523
- </Paper>
524
- )
525
- }
@@ -1,49 +0,0 @@
1
- 'use client'
2
-
3
- import { Modal, Button, Text, Group, Stack } from '@mantine/core'
4
-
5
- export interface ConfirmDeleteModalProps {
6
- isOpen: boolean
7
- title: string
8
- message: string
9
- confirmLabel?: string
10
- onConfirm: () => void
11
- onClose: () => void
12
- loading?: boolean
13
- }
14
-
15
- /**
16
- * Confirmation modal for delete operations.
17
- * Provides a clear warning UI with red/danger theme.
18
- */
19
- export function ConfirmDeleteModal({
20
- isOpen,
21
- title,
22
- message,
23
- confirmLabel = 'Delete',
24
- onConfirm,
25
- onClose,
26
- loading = false,
27
- }: ConfirmDeleteModalProps) {
28
- return (
29
- <Modal opened={isOpen} onClose={onClose} title={title} centered size="md">
30
- <Stack gap="md" data-testid="confirm-delete-modal">
31
- <Text size="sm">{message}</Text>
32
-
33
- <Group justify="flex-end" gap="sm">
34
- <Button variant="default" onClick={onClose} disabled={loading}>
35
- Cancel
36
- </Button>
37
- <Button
38
- color="red"
39
- onClick={onConfirm}
40
- loading={loading}
41
- data-testid="confirm-delete-submit"
42
- >
43
- {confirmLabel}
44
- </Button>
45
- </Group>
46
- </Stack>
47
- </Modal>
48
- )
49
- }
@@ -1,49 +0,0 @@
1
- import { createContext, useContext } from 'react'
2
- import type { CommentThread } from '../../comment-store'
3
- import type { EditorEntry } from '../Editor'
4
-
5
- /**
6
- * EditorContext provides shared state for deeply nested components
7
- * to avoid prop drilling through 5+ component levels.
8
- *
9
- * Contains:
10
- * - Core navigation state (branchName, selectedPath, currentEntry)
11
- * - Global busy state
12
- * - Comment system state (for FormRenderer, FieldWrapper, CommentsPanel)
13
- * - User context for permissions
14
- */
15
- export interface EditorContextValue {
16
- // Core navigation (used by 5+ components)
17
- branchName: string
18
- selectedPath: string
19
- currentEntry: EditorEntry | undefined
20
- busy: boolean
21
-
22
- // Comments (used by FormRenderer, FieldWrapper, CommentsPanel)
23
- comments: CommentThread[]
24
- focusedFieldPath: string | undefined
25
- highlightThreadId: string | undefined
26
-
27
- // User context
28
- currentUser: string
29
- canResolveComments: boolean
30
- }
31
-
32
- export const EditorContext = createContext<EditorContextValue | undefined>(undefined)
33
-
34
- /**
35
- * Hook to access EditorContext.
36
- * Throws an error if used outside of EditorContext.Provider.
37
- *
38
- * @example
39
- * ```tsx
40
- * const { branchName, selectedPath, currentEntry } = useEditorContext()
41
- * ```
42
- */
43
- export function useEditorContext(): EditorContextValue {
44
- const context = useContext(EditorContext)
45
- if (context === undefined) {
46
- throw new Error('useEditorContext must be used within EditorContext.Provider')
47
- }
48
- return context
49
- }
@@ -1,47 +0,0 @@
1
- import { Group, Paper, Text } from '@mantine/core'
2
-
3
- /**
4
- * Props for the EditorFooter component.
5
- */
6
- export interface EditorFooterProps {
7
- /**
8
- * Optional custom footer content.
9
- */
10
- children?: React.ReactNode
11
- }
12
-
13
- /**
14
- * Footer component for the Editor.
15
- * Displays static links (Terms, Privacy) and copyright notice.
16
- *
17
- * @example
18
- * ```tsx
19
- * <EditorFooter />
20
- * ```
21
- */
22
- export function EditorFooter({ children }: EditorFooterProps) {
23
- return (
24
- <Paper
25
- withBorder
26
- radius={0}
27
- shadow="sm"
28
- px="md"
29
- py="xs"
30
- style={{ position: 'fixed', left: 0, right: 0, bottom: 0, zIndex: 40 }}
31
- >
32
- {children ?? (
33
- <Group gap="md" justify="center">
34
- <Text size="xs" c="dimmed">
35
- Terms
36
- </Text>
37
- <Text size="xs" c="dimmed">
38
- Privacy
39
- </Text>
40
- <Text size="xs" c="dimmed">
41
- © CanopyCMS
42
- </Text>
43
- </Group>
44
- )}
45
- </Paper>
46
- )
47
- }