canopycms 0.0.0 → 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (430) hide show
  1. package/package.json +2 -3
  2. package/dist/__integration__/fixtures/content-seeds.d.ts +0 -43
  3. package/dist/__integration__/fixtures/content-seeds.d.ts.map +0 -1
  4. package/dist/__integration__/fixtures/content-seeds.js +0 -99
  5. package/dist/__integration__/fixtures/content-seeds.js.map +0 -1
  6. package/dist/__integration__/fixtures/schemas.d.ts +0 -12
  7. package/dist/__integration__/fixtures/schemas.d.ts.map +0 -1
  8. package/dist/__integration__/fixtures/schemas.js +0 -65
  9. package/dist/__integration__/fixtures/schemas.js.map +0 -1
  10. package/dist/__integration__/test-utils/api-client.d.ts +0 -123
  11. package/dist/__integration__/test-utils/api-client.d.ts.map +0 -1
  12. package/dist/__integration__/test-utils/api-client.js +0 -118
  13. package/dist/__integration__/test-utils/api-client.js.map +0 -1
  14. package/dist/__integration__/test-utils/multi-user.d.ts +0 -25
  15. package/dist/__integration__/test-utils/multi-user.d.ts.map +0 -1
  16. package/dist/__integration__/test-utils/multi-user.js +0 -105
  17. package/dist/__integration__/test-utils/multi-user.js.map +0 -1
  18. package/dist/__integration__/test-utils/test-workspace.d.ts +0 -25
  19. package/dist/__integration__/test-utils/test-workspace.d.ts.map +0 -1
  20. package/dist/__integration__/test-utils/test-workspace.js +0 -102
  21. package/dist/__integration__/test-utils/test-workspace.js.map +0 -1
  22. package/dist/editor/BranchManager.stories.d.ts +0 -8
  23. package/dist/editor/BranchManager.stories.d.ts.map +0 -1
  24. package/dist/editor/BranchManager.stories.js +0 -74
  25. package/dist/editor/BranchManager.stories.js.map +0 -1
  26. package/dist/editor/CanopyEditor.stories.d.ts +0 -7
  27. package/dist/editor/CanopyEditor.stories.d.ts.map +0 -1
  28. package/dist/editor/CanopyEditor.stories.js +0 -99
  29. package/dist/editor/CanopyEditor.stories.js.map +0 -1
  30. package/dist/editor/CommentsPanel.stories.d.ts +0 -10
  31. package/dist/editor/CommentsPanel.stories.d.ts.map +0 -1
  32. package/dist/editor/CommentsPanel.stories.js +0 -175
  33. package/dist/editor/CommentsPanel.stories.js.map +0 -1
  34. package/dist/editor/Editor.stories.d.ts +0 -7
  35. package/dist/editor/Editor.stories.d.ts.map +0 -1
  36. package/dist/editor/Editor.stories.js +0 -95
  37. package/dist/editor/Editor.stories.js.map +0 -1
  38. package/dist/editor/EditorPanes.stories.d.ts +0 -7
  39. package/dist/editor/EditorPanes.stories.d.ts.map +0 -1
  40. package/dist/editor/EditorPanes.stories.js +0 -116
  41. package/dist/editor/EditorPanes.stories.js.map +0 -1
  42. package/dist/editor/EntryNavigator.stories.d.ts +0 -8
  43. package/dist/editor/EntryNavigator.stories.d.ts.map +0 -1
  44. package/dist/editor/EntryNavigator.stories.js +0 -42
  45. package/dist/editor/EntryNavigator.stories.js.map +0 -1
  46. package/dist/editor/FormRenderer.stories.d.ts +0 -7
  47. package/dist/editor/FormRenderer.stories.d.ts.map +0 -1
  48. package/dist/editor/FormRenderer.stories.js +0 -115
  49. package/dist/editor/FormRenderer.stories.js.map +0 -1
  50. package/dist/editor/GroupManager.stories.d.ts +0 -19
  51. package/dist/editor/GroupManager.stories.d.ts.map +0 -1
  52. package/dist/editor/GroupManager.stories.js +0 -265
  53. package/dist/editor/GroupManager.stories.js.map +0 -1
  54. package/dist/editor/PermissionManager.stories.d.ts +0 -20
  55. package/dist/editor/PermissionManager.stories.d.ts.map +0 -1
  56. package/dist/editor/PermissionManager.stories.js +0 -506
  57. package/dist/editor/PermissionManager.stories.js.map +0 -1
  58. package/dist/editor/comments/FieldWrapper.stories.d.ts +0 -10
  59. package/dist/editor/comments/FieldWrapper.stories.d.ts.map +0 -1
  60. package/dist/editor/comments/FieldWrapper.stories.js +0 -173
  61. package/dist/editor/comments/FieldWrapper.stories.js.map +0 -1
  62. package/dist/editor/fields/BlockField.stories.d.ts +0 -7
  63. package/dist/editor/fields/BlockField.stories.d.ts.map +0 -1
  64. package/dist/editor/fields/BlockField.stories.js +0 -50
  65. package/dist/editor/fields/BlockField.stories.js.map +0 -1
  66. package/dist/editor/fields/fields.stories.d.ts +0 -8
  67. package/dist/editor/fields/fields.stories.d.ts.map +0 -1
  68. package/dist/editor/fields/fields.stories.js +0 -34
  69. package/dist/editor/fields/fields.stories.js.map +0 -1
  70. package/dist/test-utils/api-test-helpers.d.ts +0 -238
  71. package/dist/test-utils/api-test-helpers.d.ts.map +0 -1
  72. package/dist/test-utils/api-test-helpers.js +0 -347
  73. package/dist/test-utils/api-test-helpers.js.map +0 -1
  74. package/dist/test-utils/console-spy.d.ts +0 -56
  75. package/dist/test-utils/console-spy.d.ts.map +0 -1
  76. package/dist/test-utils/console-spy.js +0 -81
  77. package/dist/test-utils/console-spy.js.map +0 -1
  78. package/dist/test-utils/git-helpers.d.ts +0 -21
  79. package/dist/test-utils/git-helpers.d.ts.map +0 -1
  80. package/dist/test-utils/git-helpers.js +0 -23
  81. package/dist/test-utils/git-helpers.js.map +0 -1
  82. package/dist/test-utils/index.d.ts +0 -5
  83. package/dist/test-utils/index.d.ts.map +0 -1
  84. package/dist/test-utils/index.js +0 -4
  85. package/dist/test-utils/index.js.map +0 -1
  86. package/src/__integration__/errors/invalid-content.test.ts +0 -238
  87. package/src/__integration__/errors/permission-denied.test.ts +0 -220
  88. package/src/__integration__/fixtures/content-seeds.ts +0 -105
  89. package/src/__integration__/fixtures/schemas.ts +0 -67
  90. package/src/__integration__/initialization/prod-sim-init.test.ts +0 -139
  91. package/src/__integration__/permissions/path-permissions.test.ts +0 -314
  92. package/src/__integration__/permissions/role-permissions.test.ts +0 -354
  93. package/src/__integration__/permissions/settings-branch-isolation.test.ts +0 -317
  94. package/src/__integration__/settings/groups-api.test.ts +0 -403
  95. package/src/__integration__/test-utils/api-client.ts +0 -167
  96. package/src/__integration__/test-utils/multi-user.ts +0 -129
  97. package/src/__integration__/test-utils/test-workspace.ts +0 -130
  98. package/src/__integration__/user/user-context.test.ts +0 -174
  99. package/src/__integration__/validation/input-validation.test.ts +0 -166
  100. package/src/__integration__/workflows/api-editing-workflow.test.ts +0 -244
  101. package/src/__integration__/workflows/conflict-resolution.test.ts +0 -259
  102. package/src/__integration__/workflows/editing-workflow.test.ts +0 -205
  103. package/src/__integration__/workflows/review-workflow.test.ts +0 -260
  104. package/src/ai/__tests__/build.integration.test.ts +0 -224
  105. package/src/ai/__tests__/generate.integration.test.ts +0 -495
  106. package/src/ai/__tests__/handler.integration.test.ts +0 -212
  107. package/src/ai/__tests__/json-to-markdown.test.ts +0 -553
  108. package/src/ai/generate.ts +0 -410
  109. package/src/ai/handler.ts +0 -123
  110. package/src/ai/index.ts +0 -26
  111. package/src/ai/json-to-markdown.ts +0 -424
  112. package/src/ai/resolve-branch.ts +0 -34
  113. package/src/ai/types.ts +0 -160
  114. package/src/api/AGENTS.md +0 -81
  115. package/src/api/__test__/mock-client.ts +0 -404
  116. package/src/api/assets.test.ts +0 -140
  117. package/src/api/assets.ts +0 -154
  118. package/src/api/branch-merge.test.ts +0 -163
  119. package/src/api/branch-merge.ts +0 -113
  120. package/src/api/branch-review.test.ts +0 -297
  121. package/src/api/branch-review.ts +0 -136
  122. package/src/api/branch-status.test.ts +0 -85
  123. package/src/api/branch-status.ts +0 -153
  124. package/src/api/branch-withdraw.test.ts +0 -146
  125. package/src/api/branch-withdraw.ts +0 -81
  126. package/src/api/branch-workflow.integration.test.ts +0 -578
  127. package/src/api/branch.test.ts +0 -620
  128. package/src/api/branch.ts +0 -492
  129. package/src/api/client.test.ts +0 -349
  130. package/src/api/client.ts +0 -506
  131. package/src/api/comments.test.ts +0 -285
  132. package/src/api/comments.ts +0 -210
  133. package/src/api/content.test.ts +0 -345
  134. package/src/api/content.ts +0 -454
  135. package/src/api/entries.test.ts +0 -1339
  136. package/src/api/entries.ts +0 -650
  137. package/src/api/github-sync.ts +0 -144
  138. package/src/api/groups.test.ts +0 -1013
  139. package/src/api/groups.ts +0 -375
  140. package/src/api/guards.test.ts +0 -533
  141. package/src/api/guards.ts +0 -271
  142. package/src/api/index.ts +0 -87
  143. package/src/api/permissions.test.ts +0 -766
  144. package/src/api/permissions.ts +0 -334
  145. package/src/api/reference-options.ts +0 -118
  146. package/src/api/resolve-references.ts +0 -107
  147. package/src/api/route-builder.ts +0 -289
  148. package/src/api/schema.test.ts +0 -840
  149. package/src/api/schema.ts +0 -936
  150. package/src/api/security.test.ts +0 -233
  151. package/src/api/settings-helpers.ts +0 -84
  152. package/src/api/types.ts +0 -40
  153. package/src/api/user.test.ts +0 -127
  154. package/src/api/user.ts +0 -42
  155. package/src/api/validators.test.ts +0 -275
  156. package/src/api/validators.ts +0 -176
  157. package/src/asset-store.test.ts +0 -37
  158. package/src/asset-store.ts +0 -110
  159. package/src/auth/cache.ts +0 -7
  160. package/src/auth/caching-auth-plugin.test.ts +0 -154
  161. package/src/auth/caching-auth-plugin.ts +0 -109
  162. package/src/auth/context-helpers.ts +0 -75
  163. package/src/auth/file-based-auth-cache.test.ts +0 -257
  164. package/src/auth/file-based-auth-cache.ts +0 -279
  165. package/src/auth/index.ts +0 -12
  166. package/src/auth/plugin.ts +0 -51
  167. package/src/auth/types.ts +0 -38
  168. package/src/authorization/__tests__/branch.test.ts +0 -260
  169. package/src/authorization/__tests__/content.test.ts +0 -142
  170. package/src/authorization/__tests__/path.test.ts +0 -133
  171. package/src/authorization/__tests__/permissions-loader.test.ts +0 -200
  172. package/src/authorization/branch.ts +0 -94
  173. package/src/authorization/content.ts +0 -93
  174. package/src/authorization/groups/index.ts +0 -11
  175. package/src/authorization/groups/loader.ts +0 -127
  176. package/src/authorization/groups/schema.ts +0 -48
  177. package/src/authorization/helpers.ts +0 -48
  178. package/src/authorization/index.ts +0 -84
  179. package/src/authorization/path.ts +0 -112
  180. package/src/authorization/permissions/index.ts +0 -11
  181. package/src/authorization/permissions/loader.ts +0 -116
  182. package/src/authorization/permissions/schema.ts +0 -66
  183. package/src/authorization/test-utils.ts +0 -15
  184. package/src/authorization/types.ts +0 -66
  185. package/src/authorization/validation.test.ts +0 -100
  186. package/src/authorization/validation.ts +0 -62
  187. package/src/branch-metadata.test.ts +0 -168
  188. package/src/branch-metadata.ts +0 -166
  189. package/src/branch-registry.test.ts +0 -248
  190. package/src/branch-registry.ts +0 -152
  191. package/src/branch-schema-cache.test.ts +0 -275
  192. package/src/branch-schema-cache.ts +0 -189
  193. package/src/branch-workspace.test.ts +0 -183
  194. package/src/branch-workspace.ts +0 -124
  195. package/src/build/generate-ai-content.ts +0 -78
  196. package/src/build/index.ts +0 -8
  197. package/src/build-mode.ts +0 -27
  198. package/src/cli/generate-ai-content.ts +0 -100
  199. package/src/cli/init.test.ts +0 -240
  200. package/src/cli/templates/Dockerfile.cms.template +0 -19
  201. package/src/cli/templates/canopy.ts.template +0 -55
  202. package/src/cli/templates/canopycms.config.ts.template +0 -11
  203. package/src/cli/templates/deploy-cms.yml.template +0 -27
  204. package/src/cli/templates/edit-page.tsx.template +0 -32
  205. package/src/cli/templates/route.ts.template +0 -12
  206. package/src/cli/templates/schemas.ts.template +0 -16
  207. package/src/cli/templates.ts +0 -47
  208. package/src/client.ts +0 -12
  209. package/src/comment-store.test.ts +0 -442
  210. package/src/comment-store.ts +0 -301
  211. package/src/config/__tests__/config.test.ts +0 -513
  212. package/src/config/flatten.ts +0 -174
  213. package/src/config/helpers.ts +0 -167
  214. package/src/config/index.ts +0 -86
  215. package/src/config/schemas/collection.ts +0 -67
  216. package/src/config/schemas/config.ts +0 -77
  217. package/src/config/schemas/field.ts +0 -108
  218. package/src/config/schemas/media.ts +0 -27
  219. package/src/config/schemas/permissions.ts +0 -21
  220. package/src/config/types.ts +0 -321
  221. package/src/config/validation.ts +0 -70
  222. package/src/config-test.ts +0 -65
  223. package/src/config.ts +0 -11
  224. package/src/content-id-index.test.ts +0 -512
  225. package/src/content-id-index.ts +0 -479
  226. package/src/content-reader.test.ts +0 -478
  227. package/src/content-reader.ts +0 -214
  228. package/src/content-store.test.ts +0 -1126
  229. package/src/content-store.ts +0 -793
  230. package/src/context.ts +0 -111
  231. package/src/editor/BranchManager.stories.tsx +0 -80
  232. package/src/editor/BranchManager.test.tsx +0 -324
  233. package/src/editor/BranchManager.tsx +0 -461
  234. package/src/editor/CanopyEditor.stories.tsx +0 -128
  235. package/src/editor/CanopyEditor.test.tsx +0 -81
  236. package/src/editor/CanopyEditor.tsx +0 -73
  237. package/src/editor/CanopyEditorPage.test.tsx +0 -59
  238. package/src/editor/CanopyEditorPage.tsx +0 -25
  239. package/src/editor/CommentsPanel.stories.tsx +0 -184
  240. package/src/editor/CommentsPanel.tsx +0 -338
  241. package/src/editor/Editor.integration.test.tsx +0 -227
  242. package/src/editor/Editor.stories.tsx +0 -119
  243. package/src/editor/Editor.tsx +0 -1221
  244. package/src/editor/EditorPanes.stories.tsx +0 -256
  245. package/src/editor/EditorPanes.test.tsx +0 -77
  246. package/src/editor/EditorPanes.tsx +0 -180
  247. package/src/editor/EntryNavigator.stories.tsx +0 -65
  248. package/src/editor/EntryNavigator.test.tsx +0 -598
  249. package/src/editor/EntryNavigator.tsx +0 -665
  250. package/src/editor/FormRenderer.stories.tsx +0 -212
  251. package/src/editor/FormRenderer.test.tsx +0 -194
  252. package/src/editor/FormRenderer.tsx +0 -432
  253. package/src/editor/GroupManager.stories.tsx +0 -301
  254. package/src/editor/GroupManager.test.tsx +0 -682
  255. package/src/editor/GroupManager.tsx +0 -9
  256. package/src/editor/PermissionManager.stories.tsx +0 -539
  257. package/src/editor/PermissionManager.test.tsx +0 -864
  258. package/src/editor/PermissionManager.tsx +0 -12
  259. package/src/editor/canopy-path.test.ts +0 -23
  260. package/src/editor/canopy-path.ts +0 -52
  261. package/src/editor/client-reference-resolver.ts +0 -118
  262. package/src/editor/comments/BranchComments.tsx +0 -93
  263. package/src/editor/comments/EntryComments.tsx +0 -94
  264. package/src/editor/comments/FieldWrapper.stories.tsx +0 -210
  265. package/src/editor/comments/FieldWrapper.tsx +0 -129
  266. package/src/editor/comments/InlineCommentThread.test.tsx +0 -384
  267. package/src/editor/comments/InlineCommentThread.tsx +0 -246
  268. package/src/editor/comments/ThreadCarousel.test.tsx +0 -393
  269. package/src/editor/comments/ThreadCarousel.tsx +0 -525
  270. package/src/editor/components/ConfirmDeleteModal.tsx +0 -49
  271. package/src/editor/components/EditorContext.tsx +0 -49
  272. package/src/editor/components/EditorFooter.tsx +0 -47
  273. package/src/editor/components/EditorHeader.tsx +0 -492
  274. package/src/editor/components/EditorSidebar.tsx +0 -193
  275. package/src/editor/components/EntryCreateModal.tsx +0 -193
  276. package/src/editor/components/RenameEntryModal.tsx +0 -152
  277. package/src/editor/components/UserBadge.test.tsx +0 -274
  278. package/src/editor/components/UserBadge.tsx +0 -240
  279. package/src/editor/components/index.ts +0 -6
  280. package/src/editor/context/ApiClientContext.tsx +0 -56
  281. package/src/editor/context/EditorStateContext.tsx +0 -221
  282. package/src/editor/context/index.ts +0 -40
  283. package/src/editor/editor-config.test.ts +0 -385
  284. package/src/editor/editor-config.ts +0 -94
  285. package/src/editor/editor-utils.test.ts +0 -772
  286. package/src/editor/editor-utils.ts +0 -303
  287. package/src/editor/env.ts +0 -4
  288. package/src/editor/fields/BlockField.stories.tsx +0 -79
  289. package/src/editor/fields/BlockField.tsx +0 -267
  290. package/src/editor/fields/CodeField.tsx +0 -41
  291. package/src/editor/fields/MarkdownField.tsx +0 -205
  292. package/src/editor/fields/ObjectField.tsx +0 -71
  293. package/src/editor/fields/ReferenceField.tsx +0 -138
  294. package/src/editor/fields/SelectField.tsx +0 -76
  295. package/src/editor/fields/TextField.tsx +0 -35
  296. package/src/editor/fields/ToggleField.tsx +0 -37
  297. package/src/editor/fields/fields.stories.tsx +0 -40
  298. package/src/editor/group-manager/ExternalGroupsTab.tsx +0 -114
  299. package/src/editor/group-manager/GroupCard.tsx +0 -102
  300. package/src/editor/group-manager/GroupForm.tsx +0 -66
  301. package/src/editor/group-manager/InternalGroupsTab.tsx +0 -147
  302. package/src/editor/group-manager/MemberList.tsx +0 -184
  303. package/src/editor/group-manager/hooks/useExternalGroupSearch.ts +0 -63
  304. package/src/editor/group-manager/hooks/useGroupState.ts +0 -134
  305. package/src/editor/group-manager/hooks/useUserSearch.ts +0 -84
  306. package/src/editor/group-manager/index.tsx +0 -210
  307. package/src/editor/group-manager/types.ts +0 -28
  308. package/src/editor/hooks/README.md +0 -26
  309. package/src/editor/hooks/__test__/test-utils.tsx +0 -183
  310. package/src/editor/hooks/index.ts +0 -23
  311. package/src/editor/hooks/useBranchActions.test.tsx +0 -267
  312. package/src/editor/hooks/useBranchActions.tsx +0 -121
  313. package/src/editor/hooks/useBranchManager.test.tsx +0 -391
  314. package/src/editor/hooks/useBranchManager.tsx +0 -326
  315. package/src/editor/hooks/useCommentSystem.test.ts +0 -615
  316. package/src/editor/hooks/useCommentSystem.ts +0 -347
  317. package/src/editor/hooks/useDraftManager.test.ts +0 -375
  318. package/src/editor/hooks/useDraftManager.ts +0 -259
  319. package/src/editor/hooks/useEditorLayout.test.ts +0 -147
  320. package/src/editor/hooks/useEditorLayout.ts +0 -67
  321. package/src/editor/hooks/useEntryManager.test.ts +0 -588
  322. package/src/editor/hooks/useEntryManager.ts +0 -387
  323. package/src/editor/hooks/useGroupManager.test.ts +0 -277
  324. package/src/editor/hooks/useGroupManager.ts +0 -139
  325. package/src/editor/hooks/usePermissionManager.test.ts +0 -211
  326. package/src/editor/hooks/usePermissionManager.ts +0 -113
  327. package/src/editor/hooks/useReferenceResolution.ts +0 -248
  328. package/src/editor/hooks/useSchemaManager.test.ts +0 -370
  329. package/src/editor/hooks/useSchemaManager.ts +0 -310
  330. package/src/editor/hooks/useUserContext.tsx +0 -57
  331. package/src/editor/hooks/useUserMetadata.test.ts +0 -191
  332. package/src/editor/hooks/useUserMetadata.ts +0 -71
  333. package/src/editor/permission-manager/GroupSelector.tsx +0 -73
  334. package/src/editor/permission-manager/PermissionEditor.tsx +0 -321
  335. package/src/editor/permission-manager/PermissionLevelBadge.tsx +0 -53
  336. package/src/editor/permission-manager/PermissionTree.tsx +0 -237
  337. package/src/editor/permission-manager/UserSelector.tsx +0 -95
  338. package/src/editor/permission-manager/constants.tsx +0 -18
  339. package/src/editor/permission-manager/hooks/useGroupsAndUsers.ts +0 -153
  340. package/src/editor/permission-manager/hooks/usePermissionTree.ts +0 -200
  341. package/src/editor/permission-manager/index.tsx +0 -294
  342. package/src/editor/permission-manager/types.ts +0 -58
  343. package/src/editor/permission-manager/utils.ts +0 -179
  344. package/src/editor/preview-bridge.test.tsx +0 -50
  345. package/src/editor/preview-bridge.tsx +0 -294
  346. package/src/editor/schema-editor/CollectionEditor.test.tsx +0 -238
  347. package/src/editor/schema-editor/CollectionEditor.tsx +0 -520
  348. package/src/editor/schema-editor/EntryTypeEditor.test.tsx +0 -215
  349. package/src/editor/schema-editor/EntryTypeEditor.tsx +0 -367
  350. package/src/editor/schema-editor/index.ts +0 -19
  351. package/src/editor/setup-test-dom.ts +0 -10
  352. package/src/editor/test-setup.ts +0 -33
  353. package/src/editor/theme.tsx +0 -119
  354. package/src/editor/utils/env.ts +0 -39
  355. package/src/entry-schema-registry.test.ts +0 -281
  356. package/src/entry-schema-registry.ts +0 -121
  357. package/src/entry-schema.ts +0 -84
  358. package/src/git-manager.test.ts +0 -552
  359. package/src/git-manager.ts +0 -667
  360. package/src/github-service.test.ts +0 -312
  361. package/src/github-service.ts +0 -295
  362. package/src/http/handler.test.ts +0 -275
  363. package/src/http/handler.ts +0 -280
  364. package/src/http/index.ts +0 -11
  365. package/src/http/router.ts +0 -164
  366. package/src/http/types.ts +0 -44
  367. package/src/id.test.ts +0 -48
  368. package/src/id.ts +0 -22
  369. package/src/index.ts +0 -26
  370. package/src/operating-mode/__tests__/strategies.test.ts +0 -511
  371. package/src/operating-mode/client-safe-strategy.ts +0 -184
  372. package/src/operating-mode/client-unsafe-strategy.ts +0 -303
  373. package/src/operating-mode/client.ts +0 -13
  374. package/src/operating-mode/index.ts +0 -34
  375. package/src/operating-mode/types.ts +0 -186
  376. package/src/paths/__tests__/branch.test.ts +0 -53
  377. package/src/paths/__tests__/normalize.test.ts +0 -141
  378. package/src/paths/__tests__/resolve.test.ts +0 -207
  379. package/src/paths/__tests__/validation.test.ts +0 -61
  380. package/src/paths/branch.ts +0 -115
  381. package/src/paths/index.ts +0 -73
  382. package/src/paths/normalize-server.ts +0 -40
  383. package/src/paths/normalize.ts +0 -107
  384. package/src/paths/resolve.ts +0 -61
  385. package/src/paths/test-utils.ts +0 -37
  386. package/src/paths/types.ts +0 -68
  387. package/src/paths/validation.test.ts +0 -480
  388. package/src/paths/validation.ts +0 -391
  389. package/src/reference-resolver.test.ts +0 -107
  390. package/src/reference-resolver.ts +0 -157
  391. package/src/schema/index.ts +0 -29
  392. package/src/schema/meta-loader.ts +0 -366
  393. package/src/schema/resolver.ts +0 -83
  394. package/src/schema/schema-store-types.ts +0 -56
  395. package/src/schema/schema-store.test.ts +0 -816
  396. package/src/schema/schema-store.ts +0 -795
  397. package/src/schema/types.ts +0 -33
  398. package/src/schema-meta-loader.test.ts +0 -447
  399. package/src/server.ts +0 -15
  400. package/src/services.test.ts +0 -559
  401. package/src/services.ts +0 -373
  402. package/src/settings-branch-utils.ts +0 -53
  403. package/src/settings-workspace.ts +0 -156
  404. package/src/task-queue/README.md +0 -144
  405. package/src/task-queue/index.ts +0 -14
  406. package/src/task-queue/task-queue.test.ts +0 -524
  407. package/src/task-queue/task-queue.ts +0 -514
  408. package/src/task-queue/types.ts +0 -41
  409. package/src/test-utils/api-test-helpers.ts +0 -445
  410. package/src/test-utils/console-spy.test.ts +0 -14
  411. package/src/test-utils/console-spy.ts +0 -125
  412. package/src/test-utils/git-helpers.ts +0 -31
  413. package/src/test-utils/index.ts +0 -4
  414. package/src/types.ts +0 -54
  415. package/src/user.ts +0 -118
  416. package/src/utils/debug.test.ts +0 -114
  417. package/src/utils/debug.ts +0 -127
  418. package/src/utils/error.test.ts +0 -92
  419. package/src/utils/error.ts +0 -83
  420. package/src/utils/format.ts +0 -12
  421. package/src/validation/__tests__/field-traversal.test.ts +0 -263
  422. package/src/validation/deletion-checker.ts +0 -234
  423. package/src/validation/field-traversal.ts +0 -146
  424. package/src/validation/reference-validator.ts +0 -168
  425. package/src/worker/cms-worker-rebase.test.ts +0 -473
  426. package/src/worker/cms-worker.ts +0 -777
  427. package/src/worker/integration.test.ts +0 -289
  428. package/src/worker/task-queue-config.ts +0 -25
  429. package/src/worker/task-queue.test.ts +0 -452
  430. package/src/worker/task-queue.ts +0 -58
@@ -1,665 +0,0 @@
1
- 'use client'
2
-
3
- import React, { useMemo, useRef, useEffect } from 'react'
4
- import type { ContentId, LogicalPath } from '../paths/types'
5
-
6
- import {
7
- ActionIcon,
8
- Badge,
9
- Box,
10
- Group,
11
- Menu,
12
- ScrollArea,
13
- Stack,
14
- Text,
15
- Tooltip,
16
- Tree,
17
- useTree,
18
- type RenderTreeNodePayload,
19
- type TreeNodeData,
20
- rem,
21
- } from '@mantine/core'
22
- import {
23
- IconArrowDown,
24
- IconArrowUp,
25
- IconDots,
26
- IconEdit,
27
- IconFolderPlus,
28
- IconPlus,
29
- IconTrash,
30
- } from '@tabler/icons-react'
31
-
32
- import { calculatePathToEntry } from './editor-utils'
33
-
34
- // TreeController type from Mantine's useTree hook
35
- type TreeController = ReturnType<typeof useTree>
36
-
37
- export interface EntryNavItem {
38
- path: LogicalPath
39
- label: string
40
- status?: string
41
- collectionPath?: LogicalPath
42
- contentId?: ContentId // 12-char embedded ID for ordering
43
- /** True when this entry's file conflicted during rebase */
44
- conflictNotice?: boolean
45
- }
46
-
47
- export interface EntryNavCollection {
48
- path: LogicalPath
49
- label: string
50
- type: 'collection' | 'entry'
51
- contentId?: ContentId // 12-char embedded ID for ordering
52
- order?: readonly string[] // Order array for interleaving entries and children
53
- entries?: EntryNavItem[]
54
- children?: EntryNavCollection[]
55
- /** True when this collection's .collection.json conflicted during rebase */
56
- conflictNotice?: boolean
57
- onAdd?: () => void
58
- onEdit?: () => void
59
- onAddSubCollection?: () => void
60
- onDelete?: () => void
61
- }
62
-
63
- export interface EntryNavigatorProps {
64
- items?: EntryNavItem[]
65
- collections?: EntryNavCollection[]
66
- selectedPath?: string
67
- onSelect: (id: string) => void
68
- onTreeControllerReady?: (controller: TreeController) => void
69
- expandedStateRef?: React.MutableRefObject<Record<string, boolean>>
70
- onExpandedStateChange?: (state: Record<string, boolean>) => void
71
- /** Called when user requests to delete an entry */
72
- onDeleteEntry?: (path: LogicalPath) => void
73
- /** Called when user requests to rename an entry */
74
- onRenameEntry?: (path: LogicalPath) => void
75
- /** Called when user reorders an entry within a collection */
76
- onReorderEntry?: (
77
- collectionPath: LogicalPath,
78
- contentId: string,
79
- direction: 'up' | 'down',
80
- ) => void
81
- /** If provided, this collection path's node is hidden but its children are rendered at the top level */
82
- hiddenRootPath?: string
83
- }
84
-
85
- export const EntryNavigator: React.FC<EntryNavigatorProps> = ({
86
- items,
87
- collections,
88
- selectedPath,
89
- onSelect,
90
- onTreeControllerReady,
91
- expandedStateRef,
92
- onExpandedStateChange,
93
- onDeleteEntry,
94
- onRenameEntry,
95
- onReorderEntry,
96
- hiddenRootPath,
97
- }) => {
98
- const selectedNodeRef = useRef<HTMLDivElement>(null)
99
- const hasScrolledRef = useRef(false)
100
- // Track expanded state synchronously to avoid race conditions on unmount
101
- const localExpandedStateRef = useRef<Record<string, boolean>>(expandedStateRef?.current ?? {})
102
- const treeData = useMemo<TreeNodeData[]>(() => {
103
- if (collections?.length) {
104
- const toTree = (col: EntryNavCollection): TreeNodeData => {
105
- if (col.type === 'entry') {
106
- const entry = col.entries?.[0]
107
- return {
108
- value: entry?.path ?? `collection:${col.path}`,
109
- label: entry?.label ?? col.label,
110
- nodeProps: {
111
- status: entry?.status,
112
- isEntry: true,
113
- entryPath: entry?.path,
114
- },
115
- children: [],
116
- }
117
- }
118
- const entries = col.entries ?? []
119
- const childCollections = col.children ?? []
120
- const totalChildren = entries.length + childCollections.length
121
- const order = col.order ?? []
122
-
123
- // Build entry nodes keyed by contentId
124
- const entryNodesByContentId = new Map<string, TreeNodeData>()
125
- entries.forEach((entry) => {
126
- const node: TreeNodeData = {
127
- value: entry.path,
128
- label: entry.label,
129
- nodeProps: {
130
- status: entry.status,
131
- isEntry: true,
132
- entryPath: entry.path,
133
- contentId: entry.contentId,
134
- conflictNotice: entry.conflictNotice,
135
- parentCollectionPath: col.path,
136
- childIndex: 0, // Will be set below
137
- totalChildrenCount: totalChildren,
138
- },
139
- }
140
- if (entry.contentId) {
141
- entryNodesByContentId.set(entry.contentId, node)
142
- }
143
- })
144
-
145
- // Build child collection nodes keyed by contentId
146
- const childNodesByContentId = new Map<string, TreeNodeData>()
147
- childCollections.forEach((child) => {
148
- const childTree = toTree(child)
149
- const node: TreeNodeData = {
150
- ...childTree,
151
- nodeProps: {
152
- ...childTree.nodeProps,
153
- contentId: child.contentId,
154
- parentCollectionPath: col.path,
155
- childIndex: 0, // Will be set below
156
- totalChildrenCount: totalChildren,
157
- },
158
- }
159
- if (child.contentId) {
160
- childNodesByContentId.set(child.contentId, node)
161
- }
162
- })
163
-
164
- // Interleave entries and children based on order array
165
- const allChildren: TreeNodeData[] = []
166
- const usedContentIds = new Set<string>()
167
-
168
- // First, add items in order
169
- for (const contentId of order) {
170
- const entryNode = entryNodesByContentId.get(contentId)
171
- if (entryNode) {
172
- entryNode.nodeProps = {
173
- ...entryNode.nodeProps,
174
- childIndex: allChildren.length,
175
- }
176
- allChildren.push(entryNode)
177
- usedContentIds.add(contentId)
178
- continue
179
- }
180
- const childNode = childNodesByContentId.get(contentId)
181
- if (childNode) {
182
- childNode.nodeProps = {
183
- ...childNode.nodeProps,
184
- childIndex: allChildren.length,
185
- }
186
- allChildren.push(childNode)
187
- usedContentIds.add(contentId)
188
- }
189
- }
190
-
191
- // Add any entries not in order (alphabetically)
192
- const unorderedEntries = entries
193
- .filter((e) => !e.contentId || !usedContentIds.has(e.contentId))
194
- .sort((a, b) => (a.label ?? '').localeCompare(b.label ?? ''))
195
- for (const entry of unorderedEntries) {
196
- const node: TreeNodeData = {
197
- value: entry.path,
198
- label: entry.label,
199
- nodeProps: {
200
- status: entry.status,
201
- isEntry: true,
202
- entryPath: entry.path,
203
- contentId: entry.contentId,
204
- conflictNotice: entry.conflictNotice,
205
- parentCollectionPath: col.path,
206
- childIndex: allChildren.length,
207
- totalChildrenCount: totalChildren,
208
- },
209
- }
210
- allChildren.push(node)
211
- }
212
-
213
- // Add any child collections not in order (alphabetically)
214
- const unorderedChildren = childCollections
215
- .filter((c) => !c.contentId || !usedContentIds.has(c.contentId))
216
- .sort((a, b) => (a.label ?? '').localeCompare(b.label ?? ''))
217
- for (const child of unorderedChildren) {
218
- const childTree = toTree(child)
219
- const node: TreeNodeData = {
220
- ...childTree,
221
- nodeProps: {
222
- ...childTree.nodeProps,
223
- contentId: child.contentId,
224
- parentCollectionPath: col.path,
225
- childIndex: allChildren.length,
226
- totalChildrenCount: totalChildren,
227
- },
228
- }
229
- allChildren.push(node)
230
- }
231
-
232
- // Collections should always have children array (even if empty) to show chevron
233
- // This matches standard file tree UI behavior where folders always show expand/collapse
234
- return {
235
- value: `collection:${col.path}`,
236
- label: col.label,
237
- nodeProps: {
238
- isCollection: true,
239
- type: col.type,
240
- collectionPath: col.path,
241
- conflictNotice: col.conflictNotice,
242
- onAdd: col.onAdd,
243
- onEdit: col.onEdit,
244
- onAddSubCollection: col.onAddSubCollection,
245
- onDelete: col.onDelete,
246
- },
247
- children: allChildren,
248
- }
249
- }
250
-
251
- // If hiddenRootPath is set and matches a single root collection, return its children directly
252
- // This allows the root collection's order/context to be used for top-level item reordering
253
- if (hiddenRootPath && collections.length === 1 && collections[0].path === hiddenRootPath) {
254
- const rootNode = toTree(collections[0])
255
- return rootNode.children ?? []
256
- }
257
-
258
- return collections.map(toTree)
259
- }
260
-
261
- const flatItems = items ?? []
262
- return flatItems.map((item) => ({
263
- value: item.path,
264
- label: item.label,
265
- nodeProps: { status: item.status, isEntry: true, entryPath: item.path },
266
- }))
267
- }, [collections, items, hiddenRootPath])
268
-
269
- // Initialize tree controller
270
- const tree = useTree({
271
- initialExpandedState: expandedStateRef?.current ?? {},
272
- onNodeExpand: (value) => {
273
- // Update local state synchronously
274
- localExpandedStateRef.current = {
275
- ...localExpandedStateRef.current,
276
- [value]: true,
277
- }
278
- // Notify parent immediately
279
- onExpandedStateChange?.(localExpandedStateRef.current)
280
- },
281
- onNodeCollapse: (value) => {
282
- // Update local state synchronously
283
- localExpandedStateRef.current = {
284
- ...localExpandedStateRef.current,
285
- [value]: false,
286
- }
287
- // Notify parent immediately
288
- onExpandedStateChange?.(localExpandedStateRef.current)
289
- },
290
- })
291
-
292
- // Forward tree controller to parent for collapse/expand all functionality
293
-
294
- useEffect(() => {
295
- onTreeControllerReady?.(tree)
296
- // eslint-disable-next-line react-hooks/exhaustive-deps -- fire only when callback ref changes, not on tree state
297
- }, [onTreeControllerReady])
298
-
299
- // Cleanup: save current state when component unmounts
300
- // Empty dependency array ensures this only runs on mount/unmount, not on re-renders
301
- useEffect(() => {
302
- return () => {
303
- onExpandedStateChange?.(localExpandedStateRef.current)
304
- }
305
- // eslint-disable-next-line react-hooks/exhaustive-deps
306
- }, [])
307
-
308
- // Restore state on mount and when selectedPath changes
309
- useEffect(() => {
310
- if (!selectedPath || !treeData) return
311
-
312
- const savedState = expandedStateRef?.current ?? {}
313
-
314
- // Calculate path to current entry and merge with saved state
315
- const pathToEntry = calculatePathToEntry(selectedPath, treeData)
316
- const baseState = { ...savedState, ...pathToEntry }
317
-
318
- // Only update if state actually changed to avoid infinite loops
319
- const currentStateJson = JSON.stringify(tree.expandedState)
320
- const newStateJson = JSON.stringify(baseState)
321
- if (currentStateJson !== newStateJson) {
322
- tree.setExpandedState(baseState)
323
- localExpandedStateRef.current = baseState
324
- // Notify parent of the merged state
325
- onExpandedStateChange?.(baseState)
326
- }
327
- // Dependencies limited to data changes only to prevent infinite update loops
328
- // eslint-disable-next-line react-hooks/exhaustive-deps
329
- }, [selectedPath, treeData])
330
-
331
- // Auto-scroll to selected entry when drawer opens
332
- useEffect(() => {
333
- if (selectedPath && selectedNodeRef.current && !hasScrolledRef.current) {
334
- // Small delay to ensure tree expansion completes first
335
- const timeoutId = setTimeout(() => {
336
- selectedNodeRef.current?.scrollIntoView({
337
- behavior: 'smooth',
338
- block: 'center',
339
- inline: 'nearest',
340
- })
341
- hasScrolledRef.current = true
342
- }, 100)
343
-
344
- return () => clearTimeout(timeoutId)
345
- }
346
- }, [selectedPath, tree.expandedState])
347
-
348
- // Reset scroll flag when component mounts (drawer opens)
349
- useEffect(() => {
350
- hasScrolledRef.current = false
351
- }, [])
352
-
353
- const Chevron = ({ expanded, visible }: { expanded: boolean; visible: boolean }) => (
354
- <svg
355
- width="18"
356
- height="18"
357
- viewBox="0 0 24 24"
358
- fill="currentColor"
359
- aria-hidden="true"
360
- style={{ opacity: visible ? 0.9 : 0 }}
361
- >
362
- {expanded ? (
363
- <path d="M7.41 8.59 12 13.17 16.59 8.59 18 10l-6 6-6-6z" />
364
- ) : (
365
- <path d="M10 6 8.59 7.41 13.17 12 8.59 16.59 10 18l6-6z" />
366
- )}
367
- </svg>
368
- )
369
-
370
- const renderNode = ({
371
- node,
372
- elementProps,
373
- hasChildren,
374
- expanded,
375
- level,
376
- }: RenderTreeNodePayload) => {
377
- const status = node.nodeProps?.status as string | undefined
378
- const onAdd = node.nodeProps?.onAdd as (() => void) | undefined
379
- const onEdit = node.nodeProps?.onEdit as (() => void) | undefined
380
- const onAddSubCollection = node.nodeProps?.onAddSubCollection as (() => void) | undefined
381
- const onDelete = node.nodeProps?.onDelete as (() => void) | undefined
382
- const entryPath = node.nodeProps?.entryPath as LogicalPath | undefined
383
- const contentId = node.nodeProps?.contentId as string | undefined
384
- const parentCollectionPath = node.nodeProps?.parentCollectionPath as LogicalPath | undefined
385
- const childIndex = node.nodeProps?.childIndex as number | undefined
386
- const totalChildrenCount = node.nodeProps?.totalChildrenCount as number | undefined
387
- const isCollection = node.nodeProps?.isCollection as boolean | undefined
388
- const isEntry = node.nodeProps?.isEntry as boolean | undefined
389
- const conflictNotice = node.nodeProps?.conflictNotice as boolean | undefined
390
- const isLeaf = !hasChildren || isEntry
391
- const selected = node.value === selectedPath
392
-
393
- // For collections, always show chevron (even if empty) to match standard tree UI
394
- // Mantine only provides hasChildren=true if children.length > 0, but we want
395
- // collections to always be expandable
396
- const showChevron = hasChildren || Boolean(isCollection)
397
-
398
- // Reordering is available for both entries and collections that have contentId and parent path
399
- const canReorder =
400
- onReorderEntry && contentId && parentCollectionPath && typeof childIndex === 'number'
401
- const canMoveUp = canReorder && childIndex > 0
402
- const canMoveDown =
403
- canReorder && typeof totalChildrenCount === 'number' && childIndex < totalChildrenCount - 1
404
-
405
- // Determine if we should show a context menu
406
- // Collections show menu for add/edit/delete actions OR for reordering (subcollections)
407
- const hasCollectionMenu =
408
- isCollection && (onAdd || onEdit || onAddSubCollection || onDelete || canReorder)
409
- const hasEntryMenu = isEntry && entryPath && (onDeleteEntry || onRenameEntry || onReorderEntry)
410
-
411
- return (
412
- <Box
413
- {...elementProps}
414
- ref={selected ? selectedNodeRef : undefined}
415
- data-testid={`entry-nav-item-${String(node.label ?? '')
416
- .toLowerCase()
417
- .replace(/\s+/g, '-')}`}
418
- onClick={(event) => {
419
- elementProps.onClick(event)
420
- if (isLeaf && isEntry) {
421
- onSelect(node.value)
422
- }
423
- }}
424
- style={{
425
- ...elementProps.style,
426
- marginBottom: 4,
427
- borderRadius: 10,
428
- paddingInline: 10,
429
- paddingBlock: 6,
430
- paddingLeft: `calc(${rem(8)} + ${rem(level * 12)})`,
431
- backgroundColor: selected ? 'var(--mantine-color-brand-0)' : undefined,
432
- border: selected ? '1px solid var(--mantine-color-brand-3)' : '1px solid transparent',
433
- transition: 'background-color 120ms ease, border-color 120ms ease',
434
- }}
435
- >
436
- <Group gap="xs" justify="space-between" wrap="nowrap">
437
- <Group gap={6} wrap="nowrap">
438
- <Box
439
- w={18}
440
- h={18}
441
- style={{
442
- display: 'flex',
443
- alignItems: 'center',
444
- justifyContent: 'center',
445
- }}
446
- >
447
- <Chevron expanded={expanded} visible={showChevron} />
448
- </Box>
449
- <Text size="sm" fw={selected ? 600 : 500} truncate="end">
450
- {node.label}
451
- </Text>
452
- {status && (
453
- <Badge size="xs" variant="light" color="gray">
454
- {status}
455
- </Badge>
456
- )}
457
- {conflictNotice && (
458
- <Tooltip
459
- label="This content was updated on the base branch — a reviewer will reconcile"
460
- withArrow
461
- >
462
- <Badge size="xs" variant="light" color="orange" data-testid="conflict-badge">
463
- conflict
464
- </Badge>
465
- </Tooltip>
466
- )}
467
- </Group>
468
- <Group gap={4} wrap="nowrap">
469
- {hasCollectionMenu && (
470
- <Menu shadow="md" width={200} withinPortal position="bottom-end">
471
- <Menu.Target>
472
- <ActionIcon
473
- size="xs"
474
- variant="subtle"
475
- color="gray"
476
- onClick={(event) => event.stopPropagation()}
477
- aria-label="Collection actions"
478
- data-testid={`collection-menu-${String(node.label ?? '')
479
- .toLowerCase()
480
- .replace(/\s+/g, '-')}`}
481
- >
482
- <IconDots size={14} />
483
- </ActionIcon>
484
- </Menu.Target>
485
- <Menu.Dropdown>
486
- {canReorder && (
487
- <>
488
- <Menu.Item
489
- leftSection={<IconArrowUp size={14} />}
490
- disabled={!canMoveUp}
491
- onClick={(event) => {
492
- event.stopPropagation()
493
- onReorderEntry?.(parentCollectionPath!, contentId!, 'up')
494
- }}
495
- >
496
- Move Up
497
- </Menu.Item>
498
- <Menu.Item
499
- leftSection={<IconArrowDown size={14} />}
500
- disabled={!canMoveDown}
501
- onClick={(event) => {
502
- event.stopPropagation()
503
- onReorderEntry?.(parentCollectionPath!, contentId!, 'down')
504
- }}
505
- >
506
- Move Down
507
- </Menu.Item>
508
- {(onAdd || onAddSubCollection || onEdit || onDelete) && <Menu.Divider />}
509
- </>
510
- )}
511
- {onAdd && (
512
- <Menu.Item
513
- leftSection={<IconPlus size={14} />}
514
- onClick={(event) => {
515
- event.stopPropagation()
516
- onAdd()
517
- }}
518
- data-testid="add-entry-menu-item"
519
- >
520
- Add Entry
521
- </Menu.Item>
522
- )}
523
- {onAddSubCollection && (
524
- <Menu.Item
525
- leftSection={<IconFolderPlus size={14} />}
526
- onClick={(event) => {
527
- event.stopPropagation()
528
- onAddSubCollection()
529
- }}
530
- >
531
- Add Sub-Collection
532
- </Menu.Item>
533
- )}
534
- {(onAdd || onAddSubCollection) && (onEdit || onDelete) && <Menu.Divider />}
535
- {onEdit && (
536
- <Menu.Item
537
- leftSection={<IconEdit size={14} />}
538
- onClick={(event) => {
539
- event.stopPropagation()
540
- onEdit()
541
- }}
542
- >
543
- Edit Collection
544
- </Menu.Item>
545
- )}
546
- {onDelete && (
547
- <Menu.Item
548
- leftSection={<IconTrash size={14} />}
549
- color="red"
550
- onClick={(event) => {
551
- event.stopPropagation()
552
- onDelete()
553
- }}
554
- >
555
- Delete Collection
556
- </Menu.Item>
557
- )}
558
- </Menu.Dropdown>
559
- </Menu>
560
- )}
561
- {hasEntryMenu && (
562
- <Menu shadow="md" width={150} withinPortal position="bottom-end">
563
- <Menu.Target>
564
- <ActionIcon
565
- size="xs"
566
- variant="subtle"
567
- color="gray"
568
- onClick={(event) => event.stopPropagation()}
569
- aria-label="Entry actions"
570
- data-testid={`entry-menu-${String(node.label ?? '')
571
- .toLowerCase()
572
- .replace(/\s+/g, '-')}`}
573
- >
574
- <IconDots size={14} />
575
- </ActionIcon>
576
- </Menu.Target>
577
- <Menu.Dropdown>
578
- {onReorderEntry && contentId && parentCollectionPath && (
579
- <>
580
- <Menu.Item
581
- leftSection={<IconArrowUp size={14} />}
582
- disabled={!canMoveUp}
583
- onClick={(event) => {
584
- event.stopPropagation()
585
- onReorderEntry(parentCollectionPath, contentId, 'up')
586
- }}
587
- >
588
- Move Up
589
- </Menu.Item>
590
- <Menu.Item
591
- leftSection={<IconArrowDown size={14} />}
592
- disabled={!canMoveDown}
593
- onClick={(event) => {
594
- event.stopPropagation()
595
- onReorderEntry(parentCollectionPath, contentId, 'down')
596
- }}
597
- >
598
- Move Down
599
- </Menu.Item>
600
- {(onRenameEntry || onDeleteEntry) && <Menu.Divider />}
601
- </>
602
- )}
603
- {onRenameEntry && (
604
- <Menu.Item
605
- leftSection={<IconEdit size={14} />}
606
- onClick={(event) => {
607
- event.stopPropagation()
608
- onRenameEntry(entryPath)
609
- }}
610
- data-testid="rename-entry-menu-item"
611
- >
612
- Rename Entry
613
- </Menu.Item>
614
- )}
615
- {onDeleteEntry && (
616
- <Menu.Item
617
- leftSection={<IconTrash size={14} />}
618
- color="red"
619
- onClick={(event) => {
620
- event.stopPropagation()
621
- onDeleteEntry(entryPath)
622
- }}
623
- data-testid="delete-entry-menu-item"
624
- >
625
- Delete Entry
626
- </Menu.Item>
627
- )}
628
- </Menu.Dropdown>
629
- </Menu>
630
- )}
631
- </Group>
632
- </Group>
633
- </Box>
634
- )
635
- }
636
-
637
- return (
638
- <Stack
639
- h="100%"
640
- style={{ display: 'flex', flexDirection: 'column' }}
641
- gap={0}
642
- data-testid="entry-navigator"
643
- >
644
- <ScrollArea type="auto" offsetScrollbars style={{ flex: 1 }}>
645
- {treeData.length === 0 ? (
646
- <Text size="xs" c="dimmed" py="sm">
647
- No content
648
- </Text>
649
- ) : (
650
- <Box py="sm">
651
- <Tree
652
- data={treeData}
653
- tree={tree}
654
- renderNode={renderNode}
655
- selectOnClick={false}
656
- levelOffset="sm"
657
- />
658
- </Box>
659
- )}
660
- </ScrollArea>
661
- </Stack>
662
- )
663
- }
664
-
665
- export default EntryNavigator