canopycms 0.0.68-int.98 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2131 -0
- package/README.md +47 -63
- package/dist/ai/generate.d.ts +5 -0
- package/dist/ai/generate.js +244 -115
- package/dist/ai/index.d.ts +1 -1
- package/dist/ai/json-to-markdown.d.ts +21 -1
- package/dist/ai/json-to-markdown.js +120 -57
- package/dist/ai/references.d.ts +72 -0
- package/dist/ai/references.js +223 -0
- package/dist/ai/resolve-branch.js +9 -2
- package/dist/ai/to-plain-text.d.ts +17 -8
- package/dist/ai/to-plain-text.js +18 -15
- package/dist/ai/types.d.ts +84 -3
- package/dist/api/admin-branch-health.d.ts +24 -1
- package/dist/api/admin-branch-health.js +52 -20
- package/dist/api/admin.d.ts +23 -5
- package/dist/api/admin.js +36 -1
- package/dist/api/assets.js +88 -78
- package/dist/api/branch-create-window.d.ts +12 -0
- package/dist/api/branch-create-window.js +13 -0
- package/dist/api/branch-merge.d.ts +1 -1
- package/dist/api/branch-merge.js +1 -1
- package/dist/api/branch-review.d.ts +3 -3
- package/dist/api/branch-review.js +16 -7
- package/dist/api/branch-status.d.ts +16 -6
- package/dist/api/branch-status.js +57 -12
- package/dist/api/branch-withdraw.d.ts +2 -2
- package/dist/api/branch-withdraw.js +8 -3
- package/dist/api/branch.d.ts +25 -12
- package/dist/api/branch.js +164 -103
- package/dist/api/client.d.ts +78 -58
- package/dist/api/client.js +150 -117
- package/dist/api/comments.d.ts +12 -3
- package/dist/api/comments.js +118 -9
- package/dist/api/content.d.ts +9 -9
- package/dist/api/content.js +131 -22
- package/dist/api/entries-constants.d.ts +14 -3
- package/dist/api/entries-constants.js +14 -3
- package/dist/api/entries.d.ts +40 -2
- package/dist/api/entries.js +102 -6
- package/dist/api/github-sync.d.ts +19 -0
- package/dist/api/github-sync.js +50 -3
- package/dist/api/groups.d.ts +4 -4
- package/dist/api/groups.js +2 -1
- package/dist/api/guards.js +23 -3
- package/dist/api/index.d.ts +3 -1
- package/dist/api/index.js +1 -0
- package/dist/api/permissions.d.ts +21 -2
- package/dist/api/permissions.js +50 -3
- package/dist/api/request-deadline.d.ts +59 -0
- package/dist/api/request-deadline.js +73 -0
- package/dist/api/resolve-references.js +8 -7
- package/dist/api/route-builder.d.ts +14 -0
- package/dist/api/route-builder.js +14 -1
- package/dist/api/schema.d.ts +11 -9
- package/dist/api/schema.js +2 -0
- package/dist/api/settings-helpers.d.ts +5 -1
- package/dist/api/settings-helpers.js +10 -2
- package/dist/api/types.d.ts +18 -0
- package/dist/api/users-constants.d.ts +6 -0
- package/dist/api/users-constants.js +6 -0
- package/dist/assets/asset-url.d.ts +28 -16
- package/dist/assets/asset-url.js +51 -25
- package/dist/assets/finalize.js +3 -0
- package/dist/assets/index.d.ts +1 -1
- package/dist/assets/materialize.d.ts +153 -0
- package/dist/assets/materialize.js +402 -0
- package/dist/assets/store-local.d.ts +19 -5
- package/dist/assets/store-local.js +69 -10
- package/dist/assets/store-s3.d.ts +38 -7
- package/dist/assets/store-s3.js +128 -22
- package/dist/assets/transform-directives.d.ts +52 -13
- package/dist/assets/transform-directives.js +87 -27
- package/dist/assets/transform.d.ts +3 -3
- package/dist/assets/transform.js +13 -8
- package/dist/assets/types.d.ts +31 -4
- package/dist/auth/cache.d.ts +1 -1
- package/dist/auth/cache.js +1 -1
- package/dist/auth/caching-auth-plugin.d.ts +2 -0
- package/dist/auth/caching-auth-plugin.js +12 -2
- package/dist/auth/file-based-auth-cache.d.ts +8 -0
- package/dist/auth/file-based-auth-cache.js +18 -8
- package/dist/auth/person-name.d.ts +5 -0
- package/dist/auth/person-name.js +8 -0
- package/dist/auth/plugin.d.ts +10 -1
- package/dist/auth/types.d.ts +2 -0
- package/dist/auth/user-metadata-lookup.d.ts +21 -0
- package/dist/auth/user-metadata-lookup.js +116 -0
- package/dist/authorization/branch.d.ts +1 -1
- package/dist/authorization/branch.js +12 -13
- package/dist/authorization/groups/schema.d.ts +4 -4
- package/dist/authorization/helpers.d.ts +8 -0
- package/dist/authorization/helpers.js +8 -0
- package/dist/authorization/index.d.ts +1 -1
- package/dist/authorization/index.js +1 -1
- package/dist/authorization/protected-branch.d.ts +5 -4
- package/dist/authorization/protected-branch.js +7 -5
- package/dist/branch-health.d.ts +35 -8
- package/dist/branch-health.js +54 -18
- package/dist/branch-metadata-error.d.ts +27 -0
- package/dist/branch-metadata-error.js +23 -0
- package/dist/branch-metadata-file.d.ts +205 -24
- package/dist/branch-metadata-file.js +126 -25
- package/dist/branch-metadata.d.ts +45 -6
- package/dist/branch-metadata.js +142 -50
- package/dist/branch-provisioning.d.ts +167 -0
- package/dist/branch-provisioning.js +501 -0
- package/dist/branch-registry.d.ts +8 -0
- package/dist/branch-registry.js +61 -9
- package/dist/branch-schema-cache.d.ts +29 -12
- package/dist/branch-schema-cache.js +64 -21
- package/dist/branch-sparse.d.ts +23 -0
- package/dist/branch-sparse.js +118 -0
- package/dist/branch-workspace.d.ts +42 -3
- package/dist/branch-workspace.js +239 -100
- package/dist/build/asset-refs.d.ts +94 -0
- package/dist/build/asset-refs.js +267 -0
- package/dist/build/generate-ai-content.js +5 -0
- package/dist/build/inline-flight.d.ts +37 -0
- package/dist/build/inline-flight.js +142 -0
- package/dist/cli/asset-refs.d.ts +52 -0
- package/dist/cli/asset-refs.js +194 -0
- package/dist/cli/cli.d.ts +15 -1
- package/dist/cli/cli.js +8543 -3193
- package/dist/cli/configured-asset-store.d.ts +12 -0
- package/dist/cli/configured-asset-store.js +46 -0
- package/dist/cli/generate-ai-content.js +4244 -1072
- package/dist/cli/init.js +217 -126
- package/dist/cli/project-detect.d.ts +2 -0
- package/dist/cli/project-detect.js +2 -0
- package/dist/cli/template-files/Dockerfile.cms.template +13 -5
- package/dist/cli/template-files/cms-stack.ts.template +16 -13
- package/dist/client.d.ts +1 -2
- package/dist/client.js +1 -2
- package/dist/comment-store.d.ts +25 -0
- package/dist/comment-store.js +43 -8
- package/dist/config/flatten.js +2 -0
- package/dist/config/helpers.js +2 -2
- package/dist/config/index.d.ts +1 -1
- package/dist/config/schemas/config.d.ts +12 -29
- package/dist/config/schemas/config.js +9 -12
- package/dist/config/schemas/field.d.ts +3 -0
- package/dist/config/schemas/field.js +58 -4
- package/dist/config/schemas/media.d.ts +4 -13
- package/dist/config/schemas/media.js +5 -8
- package/dist/config/schemas/url.d.ts +2 -20
- package/dist/config/schemas/url.js +2 -25
- package/dist/config/types.d.ts +116 -22
- package/dist/config/types.js +3 -9
- package/dist/config/validation.d.ts +25 -4
- package/dist/config/validation.js +116 -3
- package/dist/content-id-index.js +2 -2
- package/dist/content-index-generation.d.ts +1 -1
- package/dist/content-index-generation.js +1 -1
- package/dist/content-listing.d.ts +10 -1
- package/dist/content-listing.js +22 -5
- package/dist/content-reader.d.ts +9 -0
- package/dist/content-reader.js +16 -11
- package/dist/content-store.d.ts +75 -12
- package/dist/content-store.js +249 -86
- package/dist/content-tree.js +2 -2
- package/dist/context.js +5 -2
- package/dist/dangling-reference-log.d.ts +17 -0
- package/dist/dangling-reference-log.js +29 -0
- package/dist/dev-content-watcher.d.ts +1 -1
- package/dist/dev-content-watcher.js +1 -1
- package/dist/editor/BranchManager.d.ts +23 -7
- package/dist/editor/BranchManager.js +119 -54
- package/dist/editor/CanopyEditor.d.ts +1 -1
- package/dist/editor/CanopyEditor.js +1 -2
- package/dist/editor/CommentsPanel.d.ts +14 -0
- package/dist/editor/CommentsPanel.js +68 -43
- package/dist/editor/Editor.d.ts +11 -5
- package/dist/editor/Editor.js +891 -218
- package/dist/editor/EditorAuthGate.d.ts +7 -1
- package/dist/editor/EditorAuthGate.js +41 -9
- package/dist/editor/EntryNavigator.d.ts +22 -0
- package/dist/editor/EntryNavigator.js +353 -105
- package/dist/editor/FormHeader.d.ts +25 -0
- package/dist/editor/FormHeader.js +82 -0
- package/dist/editor/FormRenderer.d.ts +27 -3
- package/dist/editor/FormRenderer.js +171 -76
- package/dist/editor/PreviewFrame.d.ts +40 -0
- package/dist/editor/PreviewFrame.js +215 -0
- package/dist/editor/PreviewPane.d.ts +47 -0
- package/dist/editor/PreviewPane.js +147 -0
- package/dist/editor/PreviewToolbarTools.d.ts +22 -0
- package/dist/editor/PreviewToolbarTools.js +73 -0
- package/dist/editor/admin/SystemHealthPanel.d.ts +2 -1
- package/dist/editor/admin/SystemHealthPanel.js +163 -33
- package/dist/editor/admin/useSystemHealth.d.ts +18 -0
- package/dist/editor/admin/useSystemHealth.js +70 -1
- package/dist/editor/branch-status.d.ts +17 -0
- package/dist/editor/branch-status.js +29 -0
- package/dist/editor/canopy-path.d.ts +9 -6
- package/dist/editor/canopy-path.js +8 -11
- package/dist/editor/client-reference-resolver.d.ts +43 -16
- package/dist/editor/client-reference-resolver.js +155 -64
- package/dist/editor/comments/BranchComments.d.ts +1 -1
- package/dist/editor/comments/BranchComments.js +2 -2
- package/dist/editor/comments/CloseRefusedNotice.d.ts +4 -0
- package/dist/editor/comments/CloseRefusedNotice.js +7 -0
- package/dist/editor/comments/CommentThreadsPopover.d.ts +47 -0
- package/dist/editor/comments/CommentThreadsPopover.js +274 -0
- package/dist/editor/comments/CommentWriteAlert.d.ts +11 -0
- package/dist/editor/comments/CommentWriteAlert.js +13 -0
- package/dist/editor/comments/EntryComments.d.ts +10 -4
- package/dist/editor/comments/EntryComments.js +14 -17
- package/dist/editor/comments/FieldWrapper.d.ts +18 -4
- package/dist/editor/comments/FieldWrapper.js +62 -28
- package/dist/editor/comments/InlineCommentThread.d.ts +9 -2
- package/dist/editor/comments/InlineCommentThread.js +11 -47
- package/dist/editor/comments/ThreadCarousel.d.ts +1 -1
- package/dist/editor/comments/ThreadCarousel.js +18 -21
- package/dist/editor/comments/ThreadReplyControls.d.ts +28 -0
- package/dist/editor/comments/ThreadReplyControls.js +92 -0
- package/dist/editor/comments/field-comment-context.d.ts +14 -0
- package/dist/editor/comments/field-comment-context.js +14 -0
- package/dist/editor/comments/form-comments.d.ts +48 -0
- package/dist/editor/comments/form-comments.js +178 -0
- package/dist/editor/comments/item-anchor-copy.d.ts +6 -0
- package/dist/editor/comments/item-anchor-copy.js +6 -0
- package/dist/editor/comments/move-focus-if-unmoved.d.ts +6 -0
- package/dist/editor/comments/move-focus-if-unmoved.js +11 -0
- package/dist/editor/comments/popover-placement.d.ts +18 -0
- package/dist/editor/comments/popover-placement.js +58 -0
- package/dist/editor/comments/use-tracked-writes.d.ts +16 -0
- package/dist/editor/comments/use-tracked-writes.js +53 -0
- package/dist/editor/components/BranchAccessList.d.ts +15 -0
- package/dist/editor/components/BranchAccessList.js +52 -0
- package/dist/editor/components/BranchLockBanner.d.ts +22 -0
- package/dist/editor/components/BranchLockBanner.js +39 -0
- package/dist/editor/components/BranchPill.d.ts +32 -0
- package/dist/editor/components/BranchPill.js +33 -0
- package/dist/editor/components/BranchesDrawer.d.ts +11 -0
- package/dist/editor/components/BranchesDrawer.js +5 -0
- package/dist/editor/components/ConfirmDeleteModal.d.ts +6 -1
- package/dist/editor/components/ConfirmDeleteModal.js +3 -2
- package/dist/editor/components/DestructiveMenuItem.d.ts +7 -0
- package/dist/editor/components/DestructiveMenuItem.js +8 -0
- package/dist/editor/components/EditorCrashScreen.d.ts +17 -0
- package/dist/editor/components/EditorCrashScreen.js +22 -0
- package/dist/editor/components/EditorErrorBoundary.d.ts +38 -0
- package/dist/editor/components/EditorErrorBoundary.js +40 -0
- package/dist/editor/components/EditorHeader.d.ts +56 -106
- package/dist/editor/components/EditorHeader.js +130 -131
- package/dist/editor/components/EditorRail.d.ts +49 -0
- package/dist/editor/components/EditorRail.js +65 -0
- package/dist/editor/components/EntryBreadcrumb.d.ts +33 -0
- package/dist/editor/components/EntryBreadcrumb.js +56 -0
- package/dist/editor/components/EntryCreateModal.d.ts +12 -7
- package/dist/editor/components/EntryCreateModal.js +51 -57
- package/dist/editor/components/NoEditPermissionNotice.d.ts +6 -5
- package/dist/editor/components/NoEditPermissionNotice.js +5 -4
- package/dist/editor/components/QuickOpenPalette.d.ts +22 -0
- package/dist/editor/components/QuickOpenPalette.js +66 -0
- package/dist/editor/components/ReadOnlyDraftNotice.d.ts +11 -0
- package/dist/editor/components/ReadOnlyDraftNotice.js +12 -0
- package/dist/editor/components/ReasonedMenuItem.d.ts +15 -0
- package/dist/editor/components/ReasonedMenuItem.js +15 -0
- package/dist/editor/components/ReferencedByList.d.ts +11 -0
- package/dist/editor/components/ReferencedByList.js +28 -0
- package/dist/editor/components/RelativeTime.d.ts +10 -0
- package/dist/editor/components/RelativeTime.js +10 -0
- package/dist/editor/components/RenameEntryModal.d.ts +9 -1
- package/dist/editor/components/RenameEntryModal.js +19 -31
- package/dist/editor/components/RetryToastMessage.d.ts +9 -0
- package/dist/editor/components/RetryToastMessage.js +6 -0
- package/dist/editor/components/SaveAllResult.d.ts +25 -0
- package/dist/editor/components/SaveAllResult.js +86 -0
- package/dist/editor/components/SaveSplitButton.d.ts +30 -0
- package/dist/editor/components/SaveSplitButton.js +108 -0
- package/dist/editor/components/StagedChangesDrawer.d.ts +39 -0
- package/dist/editor/components/StagedChangesDrawer.js +92 -0
- package/dist/editor/components/UnavailableEntryNotice.d.ts +6 -0
- package/dist/editor/components/UnavailableEntryNotice.js +9 -0
- package/dist/editor/components/UnavailableTypeMessage.d.ts +6 -0
- package/dist/editor/components/UnavailableTypeMessage.js +9 -0
- package/dist/editor/components/UndoToastMessage.d.ts +18 -0
- package/dist/editor/components/UndoToastMessage.js +10 -0
- package/dist/editor/components/UserBadge.d.ts +2 -5
- package/dist/editor/components/UserBadge.js +62 -33
- package/dist/editor/components/ValidationSummary.d.ts +14 -0
- package/dist/editor/components/ValidationSummary.js +24 -0
- package/dist/editor/components/index.d.ts +2 -2
- package/dist/editor/components/index.js +2 -2
- package/dist/editor/context/ApiClientContext.d.ts +8 -2
- package/dist/editor/context/ApiClientContext.js +19 -8
- package/dist/editor/context/AssetContext.d.ts +13 -35
- package/dist/editor/context/AssetContext.js +12 -31
- package/dist/editor/context/EditorStateContext.d.ts +4 -4
- package/dist/editor/context/EditorStateContext.js +4 -4
- package/dist/editor/context/SWRProvider.d.ts +3 -3
- package/dist/editor/context/SiteMdxAllowContext.d.ts +4 -0
- package/dist/editor/context/SiteMdxAllowContext.js +7 -0
- package/dist/editor/context/index.d.ts +2 -1
- package/dist/editor/context/index.js +2 -1
- package/dist/editor/contrast.d.ts +19 -0
- package/dist/editor/contrast.js +41 -0
- package/dist/editor/copy.d.ts +18 -0
- package/dist/editor/copy.js +18 -0
- package/dist/editor/editor-config.js +16 -0
- package/dist/editor/editor-utils.d.ts +34 -8
- package/dist/editor/editor-utils.js +42 -20
- package/dist/editor/entry-search.d.ts +20 -0
- package/dist/editor/entry-search.js +34 -0
- package/dist/editor/field-breadcrumb.d.ts +12 -0
- package/dist/editor/field-breadcrumb.js +85 -0
- package/dist/editor/field-props.d.ts +86 -0
- package/dist/editor/field-props.js +27 -0
- package/dist/editor/field-target.d.ts +30 -0
- package/dist/editor/field-target.js +77 -0
- package/dist/editor/fields/BlockField.d.ts +12 -0
- package/dist/editor/fields/BlockField.js +89 -73
- package/dist/editor/fields/CodeField.d.ts +2 -0
- package/dist/editor/fields/CodeField.js +6 -2
- package/dist/editor/fields/DateTimeField.d.ts +4 -29
- package/dist/editor/fields/DateTimeField.js +79 -41
- package/dist/editor/fields/ExpandAllButton.d.ts +6 -0
- package/dist/editor/fields/ExpandAllButton.js +4 -0
- package/dist/editor/fields/FieldCrashFallback.d.ts +17 -0
- package/dist/editor/fields/FieldCrashFallback.js +30 -0
- package/dist/editor/fields/FieldLabel.d.ts +37 -0
- package/dist/editor/fields/FieldLabel.js +19 -0
- package/dist/editor/fields/ImageField.d.ts +4 -0
- package/dist/editor/fields/ImageField.js +29 -14
- package/dist/editor/fields/InlineGroupField.js +4 -3
- package/dist/editor/fields/ItemList.d.ts +42 -0
- package/dist/editor/fields/ItemList.js +130 -0
- package/dist/editor/fields/MarkdownField.d.ts +32 -0
- package/dist/editor/fields/MarkdownField.js +223 -46
- package/dist/editor/fields/MdxImageDialog.js +1 -1
- package/dist/editor/fields/NumberField.d.ts +2 -0
- package/dist/editor/fields/NumberField.js +8 -5
- package/dist/editor/fields/NumberListField.d.ts +2 -0
- package/dist/editor/fields/NumberListField.js +19 -16
- package/dist/editor/fields/ObjectField.d.ts +2 -7
- package/dist/editor/fields/ObjectField.js +15 -5
- package/dist/editor/fields/ObjectListField.d.ts +29 -0
- package/dist/editor/fields/ObjectListField.js +57 -0
- package/dist/editor/fields/ReferenceField.d.ts +2 -0
- package/dist/editor/fields/ReferenceField.js +34 -9
- package/dist/editor/fields/SelectField.d.ts +2 -0
- package/dist/editor/fields/SelectField.js +11 -2
- package/dist/editor/fields/StringListField.d.ts +4 -1
- package/dist/editor/fields/StringListField.js +22 -8
- package/dist/editor/fields/TextField.d.ts +2 -0
- package/dist/editor/fields/TextField.js +6 -2
- package/dist/editor/fields/ToggleField.d.ts +2 -0
- package/dist/editor/fields/ToggleField.js +8 -3
- package/dist/editor/fields/entry-link/InsertEntryLink.d.ts +1 -1
- package/dist/editor/fields/entry-link/InsertEntryLink.js +1 -1
- package/dist/editor/fields/form-expansion.d.ts +9 -0
- package/dist/editor/fields/form-expansion.js +2 -0
- package/dist/editor/fields/item-expansion.d.ts +15 -0
- package/dist/editor/fields/item-expansion.js +60 -0
- package/dist/editor/fields/list-item-keys.d.ts +8 -0
- package/dist/editor/fields/list-item-keys.js +50 -0
- package/dist/editor/fields/list-item-title.d.ts +20 -0
- package/dist/editor/fields/list-item-title.js +85 -0
- package/dist/editor/fields/markdown-export-options.d.ts +2 -0
- package/dist/editor/fields/markdown-export-options.js +8 -0
- package/dist/editor/fields/markdown-fidelity-visitors.d.ts +11 -0
- package/dist/editor/fields/markdown-fidelity-visitors.js +160 -0
- package/dist/editor/fields/mdx-jsx-support.d.ts +5 -1
- package/dist/editor/fields/mdx-jsx-support.js +157 -69
- package/dist/editor/fields/rich-text-failures.d.ts +5 -0
- package/dist/editor/fields/rich-text-failures.js +26 -0
- package/dist/editor/fields/toolbar-wrap.d.ts +7 -0
- package/dist/editor/fields/toolbar-wrap.js +35 -0
- package/dist/editor/form-outline.d.ts +13 -0
- package/dist/editor/form-outline.js +70 -0
- package/dist/editor/group-manager/GroupCard.d.ts +4 -1
- package/dist/editor/group-manager/GroupCard.js +12 -3
- package/dist/editor/group-manager/GroupForm.js +1 -1
- package/dist/editor/group-manager/InternalGroupsTab.d.ts +2 -1
- package/dist/editor/group-manager/InternalGroupsTab.js +4 -4
- package/dist/editor/group-manager/MemberList.d.ts +2 -1
- package/dist/editor/group-manager/MemberList.js +15 -4
- package/dist/editor/group-manager/hooks/useGroupState.d.ts +5 -0
- package/dist/editor/group-manager/hooks/useGroupState.js +30 -7
- package/dist/editor/group-manager/index.js +34 -5
- package/dist/editor/group-manager/types.d.ts +5 -2
- package/dist/editor/hooks/create-branch-request.d.ts +20 -0
- package/dist/editor/hooks/create-branch-request.js +54 -0
- package/dist/editor/hooks/save-all.d.ts +68 -0
- package/dist/editor/hooks/save-all.js +61 -0
- package/dist/editor/hooks/useBranchActions.d.ts +11 -1
- package/dist/editor/hooks/useBranchActions.js +42 -19
- package/dist/editor/hooks/useBranchManager.d.ts +21 -0
- package/dist/editor/hooks/useBranchManager.js +321 -125
- package/dist/editor/hooks/useBranchesData.d.ts +8 -4
- package/dist/editor/hooks/useBranchesData.js +9 -5
- package/dist/editor/hooks/useCommentSystem.d.ts +14 -2
- package/dist/editor/hooks/useCommentSystem.js +79 -55
- package/dist/editor/hooks/useCommentsData.d.ts +11 -7
- package/dist/editor/hooks/useCommentsData.js +20 -19
- package/dist/editor/hooks/useDraftManager.d.ts +77 -3
- package/dist/editor/hooks/useDraftManager.js +887 -94
- package/dist/editor/hooks/useEditorLayout.d.ts +53 -7
- package/dist/editor/hooks/useEditorLayout.js +98 -20
- package/dist/editor/hooks/useEntriesData.d.ts +2 -1
- package/dist/editor/hooks/useEntriesData.js +18 -4
- package/dist/editor/hooks/useEntryManager.d.ts +41 -2
- package/dist/editor/hooks/useEntryManager.js +227 -41
- package/dist/editor/hooks/useGroupManager.js +13 -16
- package/dist/editor/hooks/usePermissionManager.js +14 -6
- package/dist/editor/hooks/usePreviewMarks.d.ts +21 -0
- package/dist/editor/hooks/usePreviewMarks.js +33 -0
- package/dist/editor/hooks/useReferenceResolution.d.ts +10 -3
- package/dist/editor/hooks/useReferenceResolution.js +34 -177
- package/dist/editor/hooks/useSchemaManager.d.ts +25 -6
- package/dist/editor/hooks/useSchemaManager.js +97 -39
- package/dist/editor/hooks/useUserMetadata.d.ts +14 -4
- package/dist/editor/hooks/useUserMetadata.js +76 -47
- package/dist/editor/hooks/user-metadata-batcher.d.ts +8 -0
- package/dist/editor/hooks/user-metadata-batcher.js +33 -0
- package/dist/editor/media/AssetCard.d.ts +6 -7
- package/dist/editor/media/AssetCard.js +24 -31
- package/dist/editor/media/AssetListRow.d.ts +16 -0
- package/dist/editor/media/AssetListRow.js +41 -0
- package/dist/editor/media/CropStep.js +6 -1
- package/dist/editor/media/MediaLibrary.d.ts +4 -3
- package/dist/editor/media/MediaLibrary.js +11 -4
- package/dist/editor/media/MediaLibraryBody.d.ts +3 -3
- package/dist/editor/media/MediaLibraryBody.js +195 -80
- package/dist/editor/media/MediaLibrarySkeleton.d.ts +6 -0
- package/dist/editor/media/MediaLibrarySkeleton.js +14 -0
- package/dist/editor/media/crop-math.d.ts +3 -4
- package/dist/editor/media/crop-math.js +11 -22
- package/dist/editor/media/editor-image-src.d.ts +8 -0
- package/dist/editor/media/editor-image-src.js +10 -0
- package/dist/editor/media/format-bytes.d.ts +2 -0
- package/dist/editor/media/format-bytes.js +23 -0
- package/dist/editor/media/media-library-prefs.d.ts +23 -0
- package/dist/editor/media/media-library-prefs.js +49 -0
- package/dist/editor/media/media-library-view.d.ts +34 -0
- package/dist/editor/media/media-library-view.js +40 -0
- package/dist/editor/media/useAssetLibrary.d.ts +30 -0
- package/dist/editor/media/useAssetLibrary.js +126 -0
- package/dist/editor/media/useStableAssetOrder.d.ts +11 -0
- package/dist/editor/media/useStableAssetOrder.js +37 -0
- package/dist/editor/media/useThumbnailFailure.d.ts +6 -0
- package/dist/editor/media/useThumbnailFailure.js +16 -0
- package/dist/editor/permission-manager/GroupSelector.js +2 -2
- package/dist/editor/permission-manager/PermissionEditor.d.ts +1 -1
- package/dist/editor/permission-manager/PermissionEditor.js +15 -4
- package/dist/editor/permission-manager/PermissionLevelBadge.js +1 -1
- package/dist/editor/permission-manager/PermissionTree.d.ts +1 -1
- package/dist/editor/permission-manager/UserSelector.d.ts +1 -1
- package/dist/editor/permission-manager/UserSelector.js +3 -3
- package/dist/editor/permission-manager/index.js +12 -3
- package/dist/editor/permission-manager/types.d.ts +5 -2
- package/dist/editor/platform.d.ts +3 -0
- package/dist/editor/platform.js +9 -0
- package/dist/editor/preview-asset-base.d.ts +9 -0
- package/dist/editor/preview-asset-base.js +17 -0
- package/dist/editor/preview-bridge.d.ts +51 -27
- package/dist/editor/preview-bridge.js +103 -144
- package/dist/editor/preview-marks.d.ts +15 -0
- package/dist/editor/preview-marks.js +74 -0
- package/dist/editor/preview-path.d.ts +12 -0
- package/dist/editor/preview-path.js +45 -1
- package/dist/editor/preview-scale.d.ts +27 -0
- package/dist/editor/preview-scale.js +34 -0
- package/dist/editor/raw-asset-base.d.ts +5 -0
- package/dist/editor/raw-asset-base.js +14 -0
- package/dist/editor/relative-time.d.ts +4 -4
- package/dist/editor/relative-time.js +16 -8
- package/dist/editor/schema-editor/CollectionEditor.d.ts +20 -3
- package/dist/editor/schema-editor/CollectionEditor.js +361 -62
- package/dist/editor/schema-editor/EntryTypeEditor.d.ts +5 -1
- package/dist/editor/schema-editor/EntryTypeEditor.js +11 -6
- package/dist/editor/schema-editor/collection-draft.d.ts +22 -0
- package/dist/editor/schema-editor/collection-draft.js +40 -0
- package/dist/editor/schema-editor/index.d.ts +1 -1
- package/dist/editor/schema-label.d.ts +10 -0
- package/dist/editor/schema-label.js +17 -0
- package/dist/editor/settings-conflict.d.ts +5 -0
- package/dist/editor/settings-conflict.js +8 -0
- package/dist/editor/shell/ActivityRail.d.ts +37 -0
- package/dist/editor/shell/ActivityRail.js +91 -0
- package/dist/editor/shell/EditorShell.d.ts +17 -0
- package/dist/editor/shell/EditorShell.js +31 -0
- package/dist/editor/shell/PaneLayout.d.ts +28 -0
- package/dist/editor/shell/PaneLayout.js +116 -0
- package/dist/editor/shell/SidePanelHost.d.ts +35 -0
- package/dist/editor/shell/SidePanelHost.js +184 -0
- package/dist/editor/shell/TopBar.d.ts +12 -0
- package/dist/editor/shell/TopBar.js +14 -0
- package/dist/editor/shell/host-chrome.d.ts +16 -0
- package/dist/editor/shell/host-chrome.js +69 -0
- package/dist/editor/slug.d.ts +16 -0
- package/dist/editor/slug.js +43 -0
- package/dist/editor/theme.d.ts +2 -1
- package/dist/editor/theme.js +314 -13
- package/dist/editor/unanswered.d.ts +17 -0
- package/dist/editor/unanswered.js +26 -0
- package/dist/editor/unavailable-entry-type.d.ts +20 -0
- package/dist/editor/unavailable-entry-type.js +28 -0
- package/dist/editor/undo-removal.d.ts +57 -0
- package/dist/editor/undo-removal.js +163 -0
- package/dist/editor/user-display.d.ts +4 -0
- package/dist/editor/user-display.js +5 -0
- package/dist/editor/utils/confirm-modal.d.ts +8 -0
- package/dist/editor/utils/confirm-modal.js +12 -0
- package/dist/editor/utils/editor-errors.d.ts +19 -0
- package/dist/editor/utils/editor-errors.js +32 -0
- package/dist/editor/utils/focus-return.d.ts +56 -0
- package/dist/editor/utils/focus-return.js +106 -0
- package/dist/entry-link-resolver.d.ts +11 -1
- package/dist/entry-link-resolver.js +65 -5
- package/dist/entry-schema-registry.d.ts +3 -3
- package/dist/entry-schema-registry.js +7 -4
- package/dist/entry-schema.d.ts +49 -3
- package/dist/entry-schema.js +18 -0
- package/dist/git-manager.d.ts +172 -10
- package/dist/git-manager.js +449 -107
- package/dist/github-service.d.ts +39 -2
- package/dist/github-service.js +101 -7
- package/dist/http/handler.js +74 -9
- package/dist/http/types.d.ts +2 -0
- package/dist/http/worker-not-ready.d.ts +9 -4
- package/dist/http/worker-not-ready.js +59 -6
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/item-keys.d.ts +46 -0
- package/dist/item-keys.js +235 -0
- package/dist/operating-mode/editor-mode-check.d.ts +15 -0
- package/dist/operating-mode/editor-mode-check.js +24 -0
- package/dist/operating-mode/mode-env.d.ts +13 -14
- package/dist/operating-mode/mode-env.js +13 -14
- package/dist/operating-mode/types.d.ts +2 -2
- package/dist/paths/branch.d.ts +0 -1
- package/dist/paths/branch.js +1 -8
- package/dist/paths/index.d.ts +1 -1
- package/dist/paths/index.js +1 -1
- package/dist/paths/validation.js +0 -2
- package/dist/preview.d.ts +8 -0
- package/dist/preview.js +7 -0
- package/dist/reference-resolver.js +1 -0
- package/dist/resolve-canopy-user.d.ts +1 -1
- package/dist/resolve-canopy-user.js +1 -1
- package/dist/schema/meta-loader.d.ts +18 -8
- package/dist/schema/meta-loader.js +42 -9
- package/dist/schema/registry-fingerprint.d.ts +14 -0
- package/dist/schema/registry-fingerprint.js +63 -0
- package/dist/schema/resolver.d.ts +7 -4
- package/dist/schema/resolver.js +7 -6
- package/dist/schema/schema-store.d.ts +7 -10
- package/dist/schema/schema-store.js +13 -11
- package/dist/schema/schema-unavailable-error.d.ts +11 -0
- package/dist/schema/schema-unavailable-error.js +15 -0
- package/dist/schema/types.d.ts +22 -0
- package/dist/schema-registry-record.d.ts +35 -0
- package/dist/schema-registry-record.js +134 -0
- package/dist/server.d.ts +79 -9
- package/dist/server.js +62 -8
- package/dist/services.d.ts +33 -5
- package/dist/services.js +155 -37
- package/dist/settings-workspace.d.ts +23 -3
- package/dist/settings-workspace.js +159 -45
- package/dist/stamp-on-publish.d.ts +36 -0
- package/dist/stamp-on-publish.js +71 -0
- package/dist/static/index.d.ts +58 -5
- package/dist/static/index.js +133 -3
- package/dist/static/seo.d.ts +5 -5
- package/dist/static/seo.js +5 -5
- package/dist/submission-attribution.d.ts +8 -0
- package/dist/submission-attribution.js +22 -0
- package/dist/system-users.d.ts +12 -0
- package/dist/system-users.js +12 -0
- package/dist/task-queue/cms-task-queue.d.ts +1 -1
- package/dist/task-queue/cms-task-queue.js +1 -1
- package/dist/task-queue/index.d.ts +1 -1
- package/dist/task-queue/index.js +1 -1
- package/dist/task-queue/task-queue.d.ts +6 -0
- package/dist/task-queue/task-queue.js +29 -0
- package/dist/task-queue/worker-status.d.ts +35 -9
- package/dist/task-queue/worker-status.js +84 -17
- package/dist/types.d.ts +90 -9
- package/dist/url-collision.js +3 -3
- package/dist/url-exclusivity-fixtures.d.ts +8 -1
- package/dist/url-exclusivity-fixtures.js +11 -1
- package/dist/user.js +2 -1
- package/dist/utils/atomic-write.js +2 -1
- package/dist/utils/base-branch.d.ts +13 -0
- package/dist/utils/base-branch.js +23 -0
- package/dist/utils/content-serialize.d.ts +15 -7
- package/dist/utils/content-serialize.js +353 -51
- package/dist/utils/content-write-lock.d.ts +6 -1
- package/dist/utils/content-write-lock.js +21 -6
- package/dist/utils/debug.d.ts +1 -1
- package/dist/utils/debug.js +5 -3
- package/dist/utils/error.js +13 -2
- package/dist/utils/escape-text.d.ts +7 -0
- package/dist/utils/escape-text.js +27 -0
- package/dist/utils/fs.d.ts +12 -4
- package/dist/utils/fs.js +18 -5
- package/dist/utils/git.d.ts +21 -1
- package/dist/utils/git.js +63 -8
- package/dist/utils/json-source-splice.d.ts +14 -0
- package/dist/utils/json-source-splice.js +120 -0
- package/dist/utils/markdown-body-splice.d.ts +39 -0
- package/dist/utils/markdown-body-splice.js +421 -0
- package/dist/utils/occ-json-write.js +18 -12
- package/dist/utils/provision-log.d.ts +25 -0
- package/dist/utils/provision-log.js +49 -0
- package/dist/utils/provisioning-lock.d.ts +32 -1
- package/dist/utils/provisioning-lock.js +78 -32
- package/dist/utils/sanitize-href.d.ts +9 -23
- package/dist/utils/sanitize-href.js +14 -28
- package/dist/utils/title-field.d.ts +10 -0
- package/dist/utils/title-field.js +47 -0
- package/dist/utils/yaml-source-splice.d.ts +58 -0
- package/dist/utils/yaml-source-splice.js +515 -0
- package/dist/validation/block-structural-keys.d.ts +1 -1
- package/dist/validation/block-structural-keys.js +1 -1
- package/dist/validation/deletion-checker.d.ts +21 -29
- package/dist/validation/deletion-checker.js +41 -117
- package/dist/validation/entry-validator.d.ts +6 -10
- package/dist/validation/entry-validator.js +19 -26
- package/dist/validation/field-traversal.d.ts +22 -0
- package/dist/validation/field-traversal.js +39 -8
- package/dist/validation/markdown-safety.d.ts +68 -0
- package/dist/validation/markdown-safety.js +596 -0
- package/dist/validation/mdx-allowlist.d.ts +55 -0
- package/dist/validation/mdx-allowlist.js +183 -0
- package/dist/validation/reference-validator.d.ts +2 -0
- package/dist/validation/reference-validator.js +3 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/worker/branch-policy.d.ts +124 -0
- package/dist/worker/branch-policy.js +243 -0
- package/dist/worker/bundle-header.d.ts +117 -0
- package/dist/worker/bundle-header.js +253 -0
- package/dist/worker/cms-worker.d.ts +236 -142
- package/dist/worker/cms-worker.js +772 -285
- package/dist/worker/gateway-egress.d.ts +43 -0
- package/dist/worker/gateway-egress.js +209 -0
- package/dist/worker/gateway-instance.d.ts +42 -0
- package/dist/worker/gateway-instance.js +129 -0
- package/dist/worker/git-process.d.ts +81 -0
- package/dist/worker/git-process.js +234 -0
- package/dist/worker/git-sync.d.ts +34 -17
- package/dist/worker/git-sync.js +394 -131
- package/dist/worker/github-auth.d.ts +9 -9
- package/dist/worker/github-auth.js +13 -15
- package/dist/worker/github-gateway-http.d.ts +62 -0
- package/dist/worker/github-gateway-http.js +977 -0
- package/dist/worker/github-gateway-wire.d.ts +590 -0
- package/dist/worker/github-gateway-wire.js +488 -0
- package/dist/worker/github-gateway.d.ts +238 -0
- package/dist/worker/github-gateway.js +726 -0
- package/dist/worker/github-mirror-upkeep.d.ts +75 -0
- package/dist/worker/github-mirror-upkeep.js +266 -0
- package/dist/worker/github-mirror.d.ts +364 -0
- package/dist/worker/github-mirror.js +1030 -0
- package/dist/worker/github-transfer.d.ts +56 -0
- package/dist/worker/github-transfer.js +444 -0
- package/dist/worker/history-rewrite.d.ts +4 -5
- package/dist/worker/history-rewrite.js +12 -17
- package/dist/worker/provisioned-workspace.d.ts +5 -5
- package/dist/worker/provisioned-workspace.js +5 -5
- package/dist/worker/rebase.d.ts +1 -1
- package/dist/worker/rebase.js +58 -54
- package/dist/worker/remote-git-maintenance.d.ts +3 -0
- package/dist/worker/remote-git-maintenance.js +12 -0
- package/dist/worker/schema-gate.d.ts +49 -0
- package/dist/worker/schema-gate.js +226 -0
- package/dist/worker/self-checks.d.ts +107 -0
- package/dist/worker/self-checks.js +358 -0
- package/dist/worker/shared-repo-git.d.ts +96 -0
- package/dist/worker/shared-repo-git.js +459 -0
- package/dist/worker/sparse-cone.d.ts +20 -0
- package/dist/worker/sparse-cone.js +136 -0
- package/dist/worker/stale-mirror.d.ts +82 -0
- package/dist/worker/stale-mirror.js +130 -0
- package/dist/worker/task-runner.d.ts +5 -3
- package/dist/worker/task-runner.js +287 -186
- package/dist/worker/worker-context.d.ts +36 -37
- package/package.json +35 -7
- package/dist/editor/EditorPanes.d.ts +0 -10
- package/dist/editor/EditorPanes.js +0 -98
- package/dist/editor/components/EditorFooter.d.ts +0 -11
- package/dist/editor/components/EditorFooter.js +0 -9
- package/dist/editor/components/EditorSidebar.d.ts +0 -67
- package/dist/editor/components/EditorSidebar.js +0 -22
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useEffect, useRef, useState } from 'react';
|
|
3
|
+
import { notifications } from '@mantine/notifications';
|
|
4
|
+
import { getErrorMessage } from '../../utils/error.js';
|
|
5
|
+
import { MayHaveLandedError } from '../unanswered.js';
|
|
6
|
+
/** Shown while a surface refuses to close because a comment write is still in flight. */
|
|
7
|
+
export const CLOSE_WAITS_FOR_WRITE = 'Still saving… You can close this once it finishes.';
|
|
8
|
+
/**
|
|
9
|
+
* Wraps a surface's comment writes: `inFlight` counts the unsettled ones, and a write that fails
|
|
10
|
+
* after the surface unmounted (the Branches drawer closed under the branch discussion, another
|
|
11
|
+
* entry or branch opened) still reports, as a toast, since nothing is left on screen to show the
|
|
12
|
+
* error. A wrapped write still rejects for its caller. `holdOpen()` is true while a write is in
|
|
13
|
+
* flight, and then sets `closeRefused` until the writes settle, which the API client's request
|
|
14
|
+
* deadline bounds, so a surface that refuses to close can say why.
|
|
15
|
+
*/
|
|
16
|
+
export function useTrackedWrites() {
|
|
17
|
+
const [inFlight, setInFlight] = useState(0);
|
|
18
|
+
const [closeRefused, setCloseRefused] = useState(false);
|
|
19
|
+
if (closeRefused && inFlight === 0)
|
|
20
|
+
setCloseRefused(false);
|
|
21
|
+
const mountedRef = useRef(true);
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
mountedRef.current = true;
|
|
24
|
+
return () => {
|
|
25
|
+
mountedRef.current = false;
|
|
26
|
+
};
|
|
27
|
+
}, []);
|
|
28
|
+
const track = (write) => async (...args) => {
|
|
29
|
+
setInFlight((n) => n + 1);
|
|
30
|
+
try {
|
|
31
|
+
await write(...args);
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
if (!mountedRef.current) {
|
|
35
|
+
notifications.show({
|
|
36
|
+
color: err instanceof MayHaveLandedError ? 'yellow' : 'red',
|
|
37
|
+
message: getErrorMessage(err),
|
|
38
|
+
autoClose: false,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
throw err;
|
|
42
|
+
}
|
|
43
|
+
finally {
|
|
44
|
+
setInFlight((n) => n - 1);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
const holdOpen = () => {
|
|
48
|
+
if (inFlight > 0)
|
|
49
|
+
setCloseRefused(true);
|
|
50
|
+
return inFlight > 0;
|
|
51
|
+
};
|
|
52
|
+
return { inFlight, track, holdOpen, closeRefused };
|
|
53
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { UserSearchResult } from '../../auth/types.js';
|
|
2
|
+
export interface BranchAccessListProps {
|
|
3
|
+
users?: readonly string[];
|
|
4
|
+
groups?: readonly string[];
|
|
5
|
+
/** ACL entries the server withheld from this viewer (`BranchListItem.withheldAccess`). */
|
|
6
|
+
withheldUsers?: number;
|
|
7
|
+
withheldGroups?: number;
|
|
8
|
+
getUserMetadata: (userId: string) => Promise<UserSearchResult | null>;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* A branch's access list as one line of text: the people the viewer's lookup names, the groups
|
|
12
|
+
* they may see, then "and N others" for the rest (docs/ux-guidelines.md, People). An unnamed
|
|
13
|
+
* person is counted, not shown as "Name unavailable".
|
|
14
|
+
*/
|
|
15
|
+
export declare function BranchAccessList({ users, groups, withheldUsers, withheldGroups, getUserMetadata, }: BranchAccessListProps): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { Skeleton, Text } from '@mantine/core';
|
|
4
|
+
import { personName } from '../../auth/person-name.js';
|
|
5
|
+
const count = (n, one, many) => `${n} ${n === 1 ? one : many}`;
|
|
6
|
+
/** The trailing count, after the names shown or standing alone. */
|
|
7
|
+
const othersLabel = (people, groups, afterNames) => {
|
|
8
|
+
if (afterNames)
|
|
9
|
+
return `and ${count(people + groups, 'other', 'others')}`;
|
|
10
|
+
if (groups === 0)
|
|
11
|
+
return count(people, 'person', 'people');
|
|
12
|
+
if (people === 0)
|
|
13
|
+
return count(groups, 'group', 'groups');
|
|
14
|
+
return `${count(people, 'person', 'people')} and ${count(groups, 'group', 'groups')}`;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* A branch's access list as one line of text: the people the viewer's lookup names, the groups
|
|
18
|
+
* they may see, then "and N others" for the rest (docs/ux-guidelines.md, People). An unnamed
|
|
19
|
+
* person is counted, not shown as "Name unavailable".
|
|
20
|
+
*/
|
|
21
|
+
export function BranchAccessList({ users = [], groups = [], withheldUsers = 0, withheldGroups = 0, getUserMetadata, }) {
|
|
22
|
+
const usersKey = users.join('\n');
|
|
23
|
+
// Tagged with what it answers, so a list or lookup that changed reads as still loading.
|
|
24
|
+
const [result, setResult] = useState();
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
let current = true;
|
|
27
|
+
void Promise.all(usersKey
|
|
28
|
+
.split('\n')
|
|
29
|
+
.filter(Boolean)
|
|
30
|
+
.map((id) => getUserMetadata(id).catch(() => null))).then((records) => {
|
|
31
|
+
if (!current)
|
|
32
|
+
return;
|
|
33
|
+
setResult({
|
|
34
|
+
usersKey,
|
|
35
|
+
lookup: getUserMetadata,
|
|
36
|
+
named: records.filter((record) => !!record && personName(record.id, record.name) !== undefined),
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
return () => {
|
|
40
|
+
current = false;
|
|
41
|
+
};
|
|
42
|
+
}, [usersKey, getUserMetadata]);
|
|
43
|
+
const named = result?.usersKey === usersKey && result.lookup === getUserMetadata ? result.named : null;
|
|
44
|
+
if (users.length + groups.length + withheldUsers + withheldGroups === 0)
|
|
45
|
+
return null;
|
|
46
|
+
const otherPeople = named ? users.length - named.length + withheldUsers : 0;
|
|
47
|
+
const shown = [...(named ?? []).map((user) => personName(user.id, user.name) ?? ''), ...groups];
|
|
48
|
+
const others = otherPeople + withheldGroups > 0
|
|
49
|
+
? othersLabel(otherPeople, withheldGroups, shown.length > 0)
|
|
50
|
+
: '';
|
|
51
|
+
return (_jsxs(Text, { size: "xs", c: "dimmed", "aria-busy": named === null || undefined, children: ['Access: ', named === null ? (_jsx(Skeleton, { component: "span", display: "inline-block", height: 10, width: 120 })) : ([shown.join(', '), others].filter(Boolean).join(' '))] }));
|
|
52
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { BranchStatus } from '../../types.js';
|
|
2
|
+
export interface BranchLockInput {
|
|
3
|
+
branchStatus: BranchStatus | undefined;
|
|
4
|
+
/** The protected base branch, read-only in prod. */
|
|
5
|
+
branchReadOnly?: boolean;
|
|
6
|
+
branchWriteBlocked?: boolean;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Which lock applies. `branchWriteBlocked` is the server's own answer (getBranchProtection), so
|
|
10
|
+
* nothing offers a write the API would reject; `branchReadOnly` only picks the message, and
|
|
11
|
+
* base-branch read-only takes precedence over a workflow status lock.
|
|
12
|
+
*/
|
|
13
|
+
export declare function branchLockState({ branchStatus, branchReadOnly, branchWriteBlocked, }: BranchLockInput): {
|
|
14
|
+
statusLocked: boolean;
|
|
15
|
+
branchDataUnavailable: boolean;
|
|
16
|
+
};
|
|
17
|
+
export interface BranchLockBannerProps extends BranchLockInput {
|
|
18
|
+
branchName: string;
|
|
19
|
+
onBranchManagerOpen: () => void;
|
|
20
|
+
}
|
|
21
|
+
/** The banner region's explanation of a read-only branch; not dismissible while it applies. */
|
|
22
|
+
export declare function BranchLockBanner({ branchName, onBranchManagerOpen, ...lock }: BranchLockBannerProps): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Alert, Box, Button, Group, Text } from '@mantine/core';
|
|
3
|
+
import { IconLock } from '@tabler/icons-react';
|
|
4
|
+
import { EDITOR_ACTIONS } from '../copy.js';
|
|
5
|
+
/**
|
|
6
|
+
* Which lock applies. `branchWriteBlocked` is the server's own answer (getBranchProtection), so
|
|
7
|
+
* nothing offers a write the API would reject; `branchReadOnly` only picks the message, and
|
|
8
|
+
* base-branch read-only takes precedence over a workflow status lock.
|
|
9
|
+
*/
|
|
10
|
+
export function branchLockState({ branchStatus, branchReadOnly = false, branchWriteBlocked = false, }) {
|
|
11
|
+
const statusLocked = branchWriteBlocked && !branchReadOnly;
|
|
12
|
+
// `branchStatus` can't describe the lock while branch data loads (undefined) or under version
|
|
13
|
+
// skew (an old server omits `branchWriteBlocked` but reports 'editing'), so both read as
|
|
14
|
+
// "details unavailable" rather than naming a status the lock contradicts.
|
|
15
|
+
const branchDataUnavailable = statusLocked && (branchStatus === undefined || branchStatus === 'editing');
|
|
16
|
+
return { statusLocked, branchDataUnavailable };
|
|
17
|
+
}
|
|
18
|
+
/** The banner region's explanation of a read-only branch; not dismissible while it applies. */
|
|
19
|
+
export function BranchLockBanner({ branchName, onBranchManagerOpen, ...lock }) {
|
|
20
|
+
const { statusLocked, branchDataUnavailable } = branchLockState(lock);
|
|
21
|
+
if (!lock.branchReadOnly && !statusLocked)
|
|
22
|
+
return null;
|
|
23
|
+
const [testId, message, action] = lock.branchReadOnly
|
|
24
|
+
? [
|
|
25
|
+
'protected-branch-banner',
|
|
26
|
+
`You are viewing the protected base branch "${branchName}". Content is read-only — create a branch to make changes.`,
|
|
27
|
+
`${EDITOR_ACTIONS.newBranch}…`,
|
|
28
|
+
]
|
|
29
|
+
: [
|
|
30
|
+
'status-locked-banner',
|
|
31
|
+
branchDataUnavailable
|
|
32
|
+
? `Branch details for "${branchName}" could not be loaded, so content is locked until they arrive. Use Switch branch… to retry.`
|
|
33
|
+
: lock.branchStatus === 'submitted'
|
|
34
|
+
? `Branch "${branchName}" is submitted for review and locked for edits. Withdraw it from review to make changes.`
|
|
35
|
+
: `Branch "${branchName}" is ${lock.branchStatus} — content is read-only.`,
|
|
36
|
+
`${EDITOR_ACTIONS.switchBranch}…`,
|
|
37
|
+
];
|
|
38
|
+
return (_jsx(Box, { px: "md", py: "sm", children: _jsx(Alert, { icon: _jsx(IconLock, { size: 16 }), color: "yellow", variant: "light", "data-testid": testId, children: _jsxs(Group, { justify: "space-between", align: "center", gap: "sm", wrap: "wrap", children: [_jsx(Text, { size: "sm", children: message }), _jsx(Button, { variant: "default", onClick: onBranchManagerOpen, children: action })] }) }) }));
|
|
39
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type Ref } from 'react';
|
|
2
|
+
import type { LogicalPath } from '../../paths/types.js';
|
|
3
|
+
export interface BranchPillProps {
|
|
4
|
+
branchName: string;
|
|
5
|
+
/** The editor is busy; with no branch name yet, that is the branch list loading. */
|
|
6
|
+
loading: boolean;
|
|
7
|
+
/** The status label ("Editing", "In review", "Protected"), when the mode shows one. */
|
|
8
|
+
status?: {
|
|
9
|
+
label: string;
|
|
10
|
+
testId: string;
|
|
11
|
+
value: string;
|
|
12
|
+
};
|
|
13
|
+
/** How many entries on the branch have unsaved changes, counting any the list can't name yet. */
|
|
14
|
+
unsavedCount: number;
|
|
15
|
+
/** The listed entries with unsaved changes. */
|
|
16
|
+
unsavedEntries: Array<{
|
|
17
|
+
path: LogicalPath;
|
|
18
|
+
label: string;
|
|
19
|
+
}>;
|
|
20
|
+
onSwitchBranch: () => void;
|
|
21
|
+
onRefreshBranch: () => void;
|
|
22
|
+
onDiscardAll: () => void;
|
|
23
|
+
onEntrySelect: (path: LogicalPath) => void;
|
|
24
|
+
/** The pill, which stands in for a menu item that opened something. */
|
|
25
|
+
pillRef?: Ref<HTMLButtonElement>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The branch's name, status and unsaved count. Its menu holds the branch actions and lists the
|
|
29
|
+
* unsaved entries, each opening that entry. Below `sm` it is the branch icon and the count, its
|
|
30
|
+
* name then in its Tooltip, accessible name and menu label: the row's actions must not clip.
|
|
31
|
+
*/
|
|
32
|
+
export declare function BranchPill({ branchName, loading, status, unsavedCount: unsaved, unsavedEntries, onSwitchBranch, onRefreshBranch, onDiscardAll, onEntrySelect, pillRef, }: BranchPillProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useRef } from 'react';
|
|
4
|
+
import { Box, Button, Menu, Text, Tooltip, VisuallyHidden } from '@mantine/core';
|
|
5
|
+
import { useMediaQuery, useMergedRef } from '@mantine/hooks';
|
|
6
|
+
import { IconChevronDown, IconGitBranch } from '@tabler/icons-react';
|
|
7
|
+
import { EDITOR_ACTIONS } from '../copy.js';
|
|
8
|
+
import { DestructiveMenuItem } from './DestructiveMenuItem.js';
|
|
9
|
+
import { ReasonedMenuItem } from './ReasonedMenuItem.js';
|
|
10
|
+
import { useMenuItemFocusReturn } from '../utils/focus-return.js';
|
|
11
|
+
const plural = (count, one, many) => `${count} ${count === 1 ? one : many}`;
|
|
12
|
+
/**
|
|
13
|
+
* The branch's name, status and unsaved count. Its menu holds the branch actions and lists the
|
|
14
|
+
* unsaved entries, each opening that entry. Below `sm` it is the branch icon and the count, its
|
|
15
|
+
* name then in its Tooltip, accessible name and menu label: the row's actions must not clip.
|
|
16
|
+
*/
|
|
17
|
+
export function BranchPill({ branchName, loading, status, unsavedCount: unsaved, unsavedEntries, onSwitchBranch, onRefreshBranch, onDiscardAll, onEntrySelect, pillRef, }) {
|
|
18
|
+
const trigger = useRef(null);
|
|
19
|
+
const triggerRef = useMergedRef(trigger, pillRef);
|
|
20
|
+
const menuFocus = useMenuItemFocusReturn(trigger);
|
|
21
|
+
const noBranch = branchName ? undefined : 'Open a branch first.';
|
|
22
|
+
const wide = useMediaQuery('(min-width: 48em)');
|
|
23
|
+
const name = branchName || (loading ? 'Loading branches…' : 'No branch open');
|
|
24
|
+
return (_jsxs(Menu, { withinPortal: true, shadow: "sm", position: "bottom-end", ...menuFocus.menu, children: [_jsx(Tooltip, { label: status ? `${name} · ${status.label}` : name, disabled: wide, events: { hover: true, focus: true, touch: false }, children: _jsx(Menu.Target, { children: _jsxs(Button, { ref: triggerRef, variant: "default", size: "sm", miw: 0, px: { base: 8, sm: 14 },
|
|
25
|
+
// The count is the bar's one branch-wide unsaved signal: the row wraps before it clips.
|
|
26
|
+
style: { flexShrink: 0 }, leftSection: _jsx(IconGitBranch, { size: 16, "aria-hidden": "true" }), rightSection: wide ? _jsx(IconChevronDown, { size: 14, "aria-hidden": "true" }) : undefined, loading: !branchName && loading, "data-testid": "branch-dropdown-button", styles: { label: { minWidth: 0, gap: 6 } }, children: [_jsx(Text, { span: true, inherit: true, truncate: "end", maw: 200, visibleFrom: "sm", children: name }), _jsx(VisuallyHidden, { component: "span", hiddenFrom: "sm", children: name }), branchName && status && (_jsxs(Text, { span: true, size: "xs", c: "dimmed", visibleFrom: "md", style: { flexShrink: 0 }, children: [_jsx("span", { "aria-hidden": "true", children: "\u00B7 " }), _jsx("span", { "data-testid": status.testId, "data-status": status.value, children: status.label })] })), unsaved > 0 && (_jsxs(Text, { span: true, size: "xs", fw: 600, px: 6, style: {
|
|
27
|
+
flexShrink: 0,
|
|
28
|
+
borderRadius: 'var(--mantine-radius-xl)',
|
|
29
|
+
background: 'var(--canopy-count-bg)',
|
|
30
|
+
}, "data-testid": "branch-unsaved-count", children: [unsaved, _jsx(Box, { component: "span", visibleFrom: "sm", children: ' unsaved' }), _jsx(VisuallyHidden, { component: "span", hiddenFrom: "sm", children: ' unsaved' })] }))] }) }) }), _jsxs(Menu.Dropdown, { "data-testid": "branch-menu", ...menuFocus.dropdown, children: [branchName && status && (_jsx(Menu.Label, { hiddenFrom: "md", children: `${branchName} · ${status.label}` })), _jsx(Menu.Item, { onClick: onSwitchBranch, "data-testid": "manage-branches-menu-item", children: `${EDITOR_ACTIONS.switchBranch}…` }), _jsx(ReasonedMenuItem, { onClick: onRefreshBranch, blockedReason: noBranch, "data-testid": "refresh-branch-menu-item", children: "Refresh branch" }), _jsx(Menu.Divider, {}), _jsx(Menu.Label, { children: "Unsaved changes" }), unsavedEntries.length === 0 ? (_jsx(Text, { size: "sm", c: "dimmed", px: "sm", py: 6, "data-testid": "edited-entries-empty", children: unsaved === 0 ? 'No unsaved changes on this branch.' : 'Loading their names…' })) : (unsavedEntries.map((entry) => (_jsx(Menu.Item, { onClick: () => onEntrySelect(entry.path), children: entry.label }, entry.path)))), _jsx(Menu.Divider, {}), _jsx(DestructiveMenuItem, { "data-testid": "discard-all-drafts-menu-item", onClick: onDiscardAll, blockedReason: noBranch ?? (unsaved === 0 ? 'Nothing to discard.' : undefined), children: unsaved > 0
|
|
31
|
+
? `Discard all changes (${plural(unsaved, 'entry', 'entries')})`
|
|
32
|
+
: 'Discard all changes' })] })] }));
|
|
33
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface BranchesDrawerProps {
|
|
3
|
+
opened: boolean;
|
|
4
|
+
onClose: () => void;
|
|
5
|
+
/** A confirm opened from inside is on screen: the drawer yields Escape to it (Mantine listens for Escape on window, capture phase). */
|
|
6
|
+
confirmOpen: boolean;
|
|
7
|
+
/** Names the element that takes focus after the drawer closes, for an opener that unmounted (a menu item). */
|
|
8
|
+
returnFocusTo?: () => HTMLElement | null;
|
|
9
|
+
children: React.ReactNode;
|
|
10
|
+
}
|
|
11
|
+
export declare const BranchesDrawer: React.FC<BranchesDrawerProps>;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Drawer, Text, Title } from '@mantine/core';
|
|
4
|
+
import { focusReturnProps } from '../utils/focus-return.js';
|
|
5
|
+
export const BranchesDrawer = ({ opened, onClose, confirmOpen, returnFocusTo, children, }) => (_jsx(Drawer, { opened: opened, onClose: onClose, closeOnEscape: !confirmOpen, position: "right", title: _jsxs("div", { children: [_jsx(Title, { order: 4, children: "Branches" }), _jsx(Text, { size: "xs", c: "dimmed", children: "Manage access, status, and lifecycle" })] }), padding: "md", size: 420, overlayProps: { blur: 2 }, ...focusReturnProps(returnFocusTo), children: children }));
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
1
2
|
export interface ConfirmDeleteModalProps {
|
|
2
3
|
isOpen: boolean;
|
|
3
4
|
title: string;
|
|
@@ -6,9 +7,13 @@ export interface ConfirmDeleteModalProps {
|
|
|
6
7
|
onConfirm: () => void;
|
|
7
8
|
onClose: () => void;
|
|
8
9
|
loading?: boolean;
|
|
10
|
+
/** Rendered between the message and the buttons. */
|
|
11
|
+
children?: ReactNode;
|
|
12
|
+
/** Where focus goes once it closes; Mantine's default, the element focused at open, without it. */
|
|
13
|
+
returnFocusTo?: () => HTMLElement | null;
|
|
9
14
|
}
|
|
10
15
|
/**
|
|
11
16
|
* Confirmation modal for delete operations.
|
|
12
17
|
* Provides a clear warning UI with red/danger theme.
|
|
13
18
|
*/
|
|
14
|
-
export declare function ConfirmDeleteModal({ isOpen, title, message, confirmLabel, onConfirm, onClose, loading, }: ConfirmDeleteModalProps): import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
export declare function ConfirmDeleteModal({ isOpen, title, message, confirmLabel, onConfirm, onClose, loading, children, returnFocusTo, }: ConfirmDeleteModalProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { Modal, Button, Text, Group, Stack } from '@mantine/core';
|
|
4
|
+
import { focusReturnProps } from '../utils/focus-return.js';
|
|
4
5
|
/**
|
|
5
6
|
* Confirmation modal for delete operations.
|
|
6
7
|
* Provides a clear warning UI with red/danger theme.
|
|
7
8
|
*/
|
|
8
|
-
export function ConfirmDeleteModal({ isOpen, title, message, confirmLabel = 'Delete', onConfirm, onClose, loading = false, }) {
|
|
9
|
-
return (_jsx(Modal, { opened: isOpen, onClose: onClose, title: title, centered: true, size: "md", children: _jsxs(Stack, { gap: "md", "data-testid": "confirm-delete-modal", children: [_jsx(Text, { size: "sm", children: message }), _jsxs(Group, { justify: "flex-end", gap: "sm", children: [_jsx(Button, { variant: "default", onClick: onClose, disabled: loading, children: "Cancel" }), _jsx(Button, { color: "red", onClick: onConfirm, loading: loading, "data-testid": "confirm-delete-submit", children: confirmLabel })] })] }) }));
|
|
9
|
+
export function ConfirmDeleteModal({ isOpen, title, message, confirmLabel = 'Delete', onConfirm, onClose, loading = false, children, returnFocusTo, }) {
|
|
10
|
+
return (_jsx(Modal, { opened: isOpen, onClose: onClose, title: title, centered: true, size: "md", closeButtonProps: { disabled: loading }, closeOnEscape: !loading, closeOnClickOutside: !loading, ...focusReturnProps(returnFocusTo), children: _jsxs(Stack, { gap: "md", "data-testid": "confirm-delete-modal", children: [_jsx(Text, { size: "sm", children: message }), children, _jsxs(Group, { justify: "flex-end", gap: "sm", children: [_jsx(Button, { size: "sm", variant: "default", onClick: onClose, disabled: loading, children: "Cancel" }), _jsx(Button, { size: "sm", color: "red", onClick: onConfirm, loading: loading, "data-testid": "confirm-delete-submit", children: confirmLabel })] })] }) }));
|
|
10
11
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type ReasonedMenuItemProps } from './ReasonedMenuItem.js';
|
|
3
|
+
/**
|
|
4
|
+
* A menu item that deletes or removes. Mantine inlines a red item's text at red.6 (3.3:1 on
|
|
5
|
+
* white), out of the theme's reach, so it takes `--canopy-danger-text`.
|
|
6
|
+
*/
|
|
7
|
+
export declare const DestructiveMenuItem: React.FC<Omit<ReasonedMenuItemProps, 'color'>>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { ReasonedMenuItem } from './ReasonedMenuItem.js';
|
|
4
|
+
/**
|
|
5
|
+
* A menu item that deletes or removes. Mantine inlines a red item's text at red.6 (3.3:1 on
|
|
6
|
+
* white), out of the theme's reach, so it takes `--canopy-danger-text`.
|
|
7
|
+
*/
|
|
8
|
+
export const DestructiveMenuItem = (props) => (_jsx(ReasonedMenuItem, { color: "red", c: "var(--canopy-danger-text)", ...props }));
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type CanopyThemeOptions } from '../theme.js';
|
|
3
|
+
/**
|
|
4
|
+
* The editor's URL opening no entry, keeping the branch: an empty `entry` shows the navigator
|
|
5
|
+
* rather than the first entry, which may be the one that crashed.
|
|
6
|
+
* @internal Exported for tests.
|
|
7
|
+
*/
|
|
8
|
+
export declare const entriesUrl: (href: string) => string;
|
|
9
|
+
/**
|
|
10
|
+
* The last resort when the editor itself throws while rendering. It brings its own theme
|
|
11
|
+
* provider, the editor's having gone with the crash. Edits made before the crash are in the
|
|
12
|
+
* browser's draft store, so a reload offers them; the edit whose render crashed is not.
|
|
13
|
+
*/
|
|
14
|
+
export declare const EditorCrashBoundary: React.FC<{
|
|
15
|
+
themeOptions?: CanopyThemeOptions;
|
|
16
|
+
children: React.ReactNode;
|
|
17
|
+
}>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Button, Center, Group, Paper, Stack, Text, Title } from '@mantine/core';
|
|
4
|
+
import { IconAlertTriangle, IconArrowLeft, IconRefresh } from '@tabler/icons-react';
|
|
5
|
+
import { CanopyCMSProvider } from '../theme.js';
|
|
6
|
+
import { CopyErrorDetailsButton, EditorErrorBoundary } from './EditorErrorBoundary.js';
|
|
7
|
+
/**
|
|
8
|
+
* The editor's URL opening no entry, keeping the branch: an empty `entry` shows the navigator
|
|
9
|
+
* rather than the first entry, which may be the one that crashed.
|
|
10
|
+
* @internal Exported for tests.
|
|
11
|
+
*/
|
|
12
|
+
export const entriesUrl = (href) => {
|
|
13
|
+
const url = new URL(href);
|
|
14
|
+
url.searchParams.set('entry', '');
|
|
15
|
+
return url.toString();
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* The last resort when the editor itself throws while rendering. It brings its own theme
|
|
19
|
+
* provider, the editor's having gone with the crash. Edits made before the crash are in the
|
|
20
|
+
* browser's draft store, so a reload offers them; the edit whose render crashed is not.
|
|
21
|
+
*/
|
|
22
|
+
export const EditorCrashBoundary = ({ themeOptions, children }) => (_jsx(EditorErrorBoundary, { context: { boundary: 'editor' }, fallback: (caught) => (_jsx(CanopyCMSProvider, { ...themeOptions, withNotifications: false, children: _jsx(Center, { mih: "100vh", p: "md", "data-testid": "editor-crash-screen", children: _jsx(Paper, { withBorder: true, p: "xl", maw: 560, children: _jsxs(Stack, { gap: "md", children: [_jsxs(Group, { gap: "sm", children: [_jsx(IconAlertTriangle, { size: 24, color: "var(--canopy-danger-text)" }), _jsx(Title, { order: 3, children: "The editor stopped working" })] }), _jsx(Text, { size: "sm", children: "Something went wrong while showing this page. Unsaved changes made before the error are kept in this browser and come back when the editor opens again." }), _jsx(Text, { size: "sm", children: "Reload to try again. If it happens again on the same entry, go back to the list of entries and copy the error details for whoever looks after the site." }), _jsxs(Group, { gap: "sm", children: [_jsx(Button, { size: "sm", leftSection: _jsx(IconRefresh, { size: 16 }), onClick: () => window.location.reload(), children: "Reload" }), _jsx(Button, { size: "sm", variant: "default", leftSection: _jsx(IconArrowLeft, { size: 16 }), onClick: () => window.location.assign(entriesUrl(window.location.href)), children: "Back to entries" }), _jsx(CopyErrorDetailsButton, { caught: caught, size: "sm" })] })] }) }) }) })), children: children }));
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type EditorErrorContext } from '../utils/editor-errors.js';
|
|
3
|
+
export interface CaughtEditorError {
|
|
4
|
+
error: unknown;
|
|
5
|
+
context: EditorErrorContext;
|
|
6
|
+
}
|
|
7
|
+
interface EditorErrorBoundaryProps {
|
|
8
|
+
context: Omit<EditorErrorContext, 'componentStack'>;
|
|
9
|
+
/** A change shows the children again, without remounting healthy ones. */
|
|
10
|
+
resetKey?: string;
|
|
11
|
+
fallback: (caught: CaughtEditorError) => React.ReactNode;
|
|
12
|
+
/** Runs after the error is reported. */
|
|
13
|
+
onCaught?: (caught: CaughtEditorError) => void;
|
|
14
|
+
children: React.ReactNode;
|
|
15
|
+
}
|
|
16
|
+
interface EditorErrorBoundaryState {
|
|
17
|
+
error: {
|
|
18
|
+
value: unknown;
|
|
19
|
+
componentStack?: string;
|
|
20
|
+
} | null;
|
|
21
|
+
/** The `resetKey` the boundary last rendered under. */
|
|
22
|
+
renderedUnder: string | undefined;
|
|
23
|
+
}
|
|
24
|
+
/** Catches errors thrown while rendering its children and reports each through `reportEditorError`. */
|
|
25
|
+
export declare class EditorErrorBoundary extends React.Component<EditorErrorBoundaryProps, EditorErrorBoundaryState> {
|
|
26
|
+
state: EditorErrorBoundaryState;
|
|
27
|
+
static getDerivedStateFromError(error: unknown): Partial<EditorErrorBoundaryState>;
|
|
28
|
+
static getDerivedStateFromProps(props: EditorErrorBoundaryProps, state: EditorErrorBoundaryState): Partial<EditorErrorBoundaryState> | null;
|
|
29
|
+
componentDidCatch(error: unknown, info: React.ErrorInfo): void;
|
|
30
|
+
private caught;
|
|
31
|
+
render(): React.ReactNode;
|
|
32
|
+
}
|
|
33
|
+
/** Copies the sanitised details of a caught error, for the author to pass on. */
|
|
34
|
+
export declare const CopyErrorDetailsButton: React.FC<{
|
|
35
|
+
caught: CaughtEditorError;
|
|
36
|
+
size?: 'xs' | 'sm';
|
|
37
|
+
}>;
|
|
38
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { Button, CopyButton } from '@mantine/core';
|
|
5
|
+
import { IconCheck, IconCopy } from '@tabler/icons-react';
|
|
6
|
+
import { formatErrorDetails, reportEditorError, } from '../utils/editor-errors.js';
|
|
7
|
+
/** Catches errors thrown while rendering its children and reports each through `reportEditorError`. */
|
|
8
|
+
export class EditorErrorBoundary extends React.Component {
|
|
9
|
+
constructor() {
|
|
10
|
+
super(...arguments);
|
|
11
|
+
this.state = { error: null, renderedUnder: this.props.resetKey };
|
|
12
|
+
}
|
|
13
|
+
static getDerivedStateFromError(error) {
|
|
14
|
+
return { error: { value: error } };
|
|
15
|
+
}
|
|
16
|
+
static getDerivedStateFromProps(props, state) {
|
|
17
|
+
if (props.resetKey === state.renderedUnder)
|
|
18
|
+
return null;
|
|
19
|
+
return { error: null, renderedUnder: props.resetKey };
|
|
20
|
+
}
|
|
21
|
+
componentDidCatch(error, info) {
|
|
22
|
+
const caught = this.caught({ value: error, componentStack: info.componentStack ?? undefined });
|
|
23
|
+
reportEditorError(error, caught.context);
|
|
24
|
+
this.setState({ error: { value: error, componentStack: caught.context.componentStack } });
|
|
25
|
+
this.props.onCaught?.(caught);
|
|
26
|
+
}
|
|
27
|
+
caught(error) {
|
|
28
|
+
return {
|
|
29
|
+
error: error.value,
|
|
30
|
+
context: { ...this.props.context, componentStack: error.componentStack },
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
render() {
|
|
34
|
+
return this.state.error
|
|
35
|
+
? this.props.fallback(this.caught(this.state.error))
|
|
36
|
+
: this.props.children;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/** Copies the sanitised details of a caught error, for the author to pass on. */
|
|
40
|
+
export const CopyErrorDetailsButton = ({ caught, size = 'xs' }) => (_jsx(CopyButton, { value: formatErrorDetails(caught.error, caught.context), children: ({ copied, copy }) => (_jsx(Button, { size: size, variant: "light", color: copied ? 'teal' : 'gray', leftSection: copied ? _jsx(IconCheck, { size: 14 }) : _jsx(IconCopy, { size: 14 }), onClick: copy, "data-testid": "copy-error-details", children: copied ? 'Copied' : 'Copy error details' })) }));
|