fix: Before/After creation options appear in menu when no permission on parent doc (#12629)

* fix: Before/After creation options appear in menu when no permission on parent

closes #12624

* fix: Manager of root document sees non-functional Before/After create options

Before/After only gated on the team-level createDocument ability, so a user
with document-level manager access (but no collection access) saw the options
yet hit a backend rejection. Gate on the actual sibling location instead,
mirroring authorizeDocumentCreate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Tom Moor
2026-06-08 17:44:09 -04:00
committed by GitHub
parent bc5ffb79b2
commit 709184ae0b
+22 -2
View File
@@ -240,6 +240,26 @@ function findDocumentSiblingIndex(
return siblings?.findIndex((node) => node.id === document.id) ?? -1;
}
/**
* Determines whether the user can create a sibling of the given document.
* A sibling shares the document's parent, so this mirrors the backend's
* create authorization: create permission on the parent document, or on the
* collection when the document is at the root.
*
* @param stores - the root stores.
* @param document - the document to create a sibling of.
* @returns true if the user can create a sibling.
*/
function canCreateSiblingDocument(
stores: ActionContext["stores"],
document: { collectionId?: string | null; parentDocumentId?: string }
): boolean {
return document.parentDocumentId
? stores.policies.abilities(document.parentDocumentId).createChildDocument
: !!document.collectionId &&
stores.policies.abilities(document.collectionId).createDocument;
}
export const createNestedDocument = createInternalLinkAction({
name: ({ t }) => t("Nested document"),
analyticsName: "New document",
@@ -279,7 +299,7 @@ const createDocumentBefore = createInternalLinkAction({
if (collection?.sort.field === "title") {
return false;
}
return stores.policies.abilities(currentTeamId).createDocument;
return canCreateSiblingDocument(stores, document);
},
to: ({ activeDocumentId, stores, sidebarContext }) => {
const document = activeDocumentId
@@ -321,7 +341,7 @@ const createDocumentAfter = createInternalLinkAction({
if (collection?.sort.field === "title") {
return false;
}
return stores.policies.abilities(currentTeamId).createDocument;
return canCreateSiblingDocument(stores, document);
},
to: ({ activeDocumentId, stores, sidebarContext }) => {
const document = activeDocumentId