Skip to content

Commit b60039b

Browse files
SamyPesseemmerich
andauthored
Fix links to other spaces in a section (#3409)
Co-authored-by: Steven H <[email protected]>
1 parent 8fe9c9a commit b60039b

File tree

4 files changed

+84
-37
lines changed

4 files changed

+84
-37
lines changed

.changeset/rotten-pianos-cheat.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"gitbook": patch
3+
---
4+
5+
Fix links to other spaces within a section.

packages/gitbook/src/components/Search/server-actions.tsx

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import type { GitBookBaseContext, GitBookSiteContext } from '@/lib/context';
44
import { resolvePageId } from '@/lib/pages';
55
import { fetchServerActionSiteContext, getServerActionBaseContext } from '@/lib/server-actions';
6-
import { findSiteSpaceById, getSiteStructureSections } from '@/lib/sites';
6+
import { findSiteSpaceBy } from '@/lib/sites';
77
import { filterOutNullable } from '@/lib/typescript';
88
import type {
99
Revision,
@@ -256,24 +256,20 @@ async function searchSiteContent(
256256
return (
257257
await Promise.all(
258258
searchResults.map(async (spaceItem) => {
259-
const sections = getSiteStructureSections(structure).flatMap((item) =>
260-
item.object === 'site-section-group' ? [item, ...item.sections] : item
259+
const found = findSiteSpaceBy(
260+
structure,
261+
(siteSpace) => siteSpace.space.id === spaceItem.id
261262
);
262-
const siteSpace = findSiteSpaceById(structure, spaceItem.id);
263-
const siteSection = sections.find(
264-
(section) => section.id === siteSpace?.section
265-
) as SiteSection;
266-
const siteSectionGroup = siteSection?.sectionGroup
267-
? sections.find((sectionGroup) => sectionGroup.id === siteSection.sectionGroup)
268-
: null;
263+
const siteSection = found?.siteSection;
264+
const siteSectionGroup = found?.siteSectionGroup;
269265

270266
return Promise.all(
271267
spaceItem.pages.map((pageItem) =>
272268
transformSitePageResult(context, {
273269
pageItem,
274270
spaceItem,
275-
space: siteSpace?.space,
276-
spaceURL: siteSpace?.urls.published,
271+
space: found?.siteSpace.space,
272+
spaceURL: found?.siteSpace.urls.published,
277273
siteSection: siteSection ?? undefined,
278274
siteSectionGroup: (siteSectionGroup as SiteSectionGroup) ?? undefined,
279275
})
@@ -313,8 +309,11 @@ async function transformAnswer(
313309
}
314310

315311
// Find the siteSpace in case it is nested in a site section so we can resolve the URL appropriately
316-
const siteSpace = findSiteSpaceById(context.structure, source.space);
317-
const spaceURL = siteSpace?.urls.published;
312+
const found = findSiteSpaceBy(
313+
context.structure,
314+
(siteSpace) => siteSpace.space.id === source.space
315+
);
316+
const spaceURL = found?.siteSpace.urls.published;
318317

319318
const href = spaceURL
320319
? joinPathWithBaseURL(spaceURL, page.page.path)

packages/gitbook/src/lib/references.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import { PageIcon } from '@/components/PageIcon';
3333
import { getGitBookAppHref } from './app';
3434
import { getBlockById, getBlockTitle } from './document';
3535
import { resolvePageId } from './pages';
36-
import { findSiteSpaceById, getFallbackSiteSpacePath } from './sites';
36+
import { findSiteSpaceBy, getFallbackSiteSpacePath } from './sites';
3737
import type { ClassValue } from './tailwind';
3838
import { filterOutNullable } from './typescript';
3939

@@ -315,9 +315,12 @@ async function getBestTargetSpace(
315315
// In the context of sites, we try to find our target space in the site structure.
316316
// because the url of this space will be in the same site.
317317
if ('site' in context) {
318-
const siteSpace = findSiteSpaceById(context.structure, spaceId);
319-
if (siteSpace) {
320-
return { space: siteSpace.space, siteSpace };
318+
const found = findSiteSpaceBy(
319+
context.structure,
320+
(siteSpace) => siteSpace.space.id === spaceId
321+
);
322+
if (found) {
323+
return { space: found.siteSpace.space, siteSpace: found.siteSpace };
321324
}
322325
}
323326

packages/gitbook/src/lib/sites.ts

Lines changed: 59 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -48,18 +48,46 @@ export function listAllSiteSpaces(siteStructure: SiteStructure) {
4848
/**
4949
* Find a site space by its spaceId in a site structure.
5050
*/
51-
export function findSiteSpaceById(siteStructure: SiteStructure, spaceId: string): SiteSpace | null {
51+
export function findSiteSpaceBy(
52+
siteStructure: SiteStructure,
53+
predicate: (siteSpace: SiteSpace) => boolean
54+
): {
55+
siteSpace: SiteSpace;
56+
siteSection: SiteSection | null;
57+
siteSectionGroup: SiteSectionGroup | null;
58+
} | null {
5259
if (siteStructure.type === 'siteSpaces') {
53-
return siteStructure.structure.find((siteSpace) => siteSpace.space.id === spaceId) ?? null;
60+
const siteSpace = siteStructure.structure.find(predicate) ?? null;
61+
if (siteSpace) {
62+
return {
63+
siteSpace,
64+
siteSection: null,
65+
siteSectionGroup: null,
66+
};
67+
}
68+
69+
return null;
5470
}
5571

56-
for (const section of siteStructure.structure) {
57-
const siteSpace =
58-
section.object === 'site-section'
59-
? findSiteSpaceByIdInSiteSpaces(section.siteSpaces, spaceId)
60-
: findSiteSpaceByIdInSections(section.sections, spaceId);
61-
if (siteSpace) {
62-
return siteSpace;
72+
for (const sectionOrGroup of siteStructure.structure) {
73+
if (sectionOrGroup.object === 'site-section') {
74+
const siteSpace = findSiteSpaceByIdInSiteSpaces(sectionOrGroup.siteSpaces, predicate);
75+
if (siteSpace) {
76+
return {
77+
siteSpace,
78+
siteSection: sectionOrGroup,
79+
siteSectionGroup: null,
80+
};
81+
}
82+
} else {
83+
const found = findSiteSpaceByIdInSections(sectionOrGroup.sections, predicate);
84+
if (found) {
85+
return {
86+
siteSpace: found.siteSpace,
87+
siteSection: found.siteSection,
88+
siteSectionGroup: sectionOrGroup,
89+
};
90+
}
6391
}
6492
}
6593

@@ -94,25 +122,37 @@ export function getSiteSpaceURL(context: GitBookSiteContext, siteSpace: SiteSpac
94122

95123
/**
96124
* Get the path of a site space in the current site.
97-
* This doesn't return the most optimized path, as it doesn't take into account which one is the default one.
98125
*/
99126
export function getFallbackSiteSpacePath(context: GitBookSiteContext, siteSpace: SiteSpace) {
100-
const { sections } = context;
101-
return sections?.current ? joinPath(sections.current.path, siteSpace.path) : siteSpace.path;
127+
const found = findSiteSpaceBy(context.structure, (entry) => entry.id === siteSpace.id);
128+
// don't include the path for the default site space
129+
const siteSpacePath = siteSpace.default ? '' : siteSpace.path;
130+
131+
// for non-default site sections, include the section path.
132+
if (found?.siteSection && !found?.siteSection.default) {
133+
return joinPath(found.siteSection.path, siteSpacePath);
134+
}
135+
136+
return siteSpacePath;
102137
}
103138

104-
function findSiteSpaceByIdInSections(sections: SiteSection[], spaceId: string): SiteSpace | null {
105-
for (const section of sections) {
106-
const siteSpace =
107-
section.siteSpaces.find((siteSpace) => siteSpace.space.id === spaceId) ?? null;
139+
function findSiteSpaceByIdInSections(
140+
sections: SiteSection[],
141+
predicate: (siteSpace: SiteSpace) => boolean
142+
): { siteSpace: SiteSpace; siteSection: SiteSection } | null {
143+
for (const siteSection of sections) {
144+
const siteSpace = siteSection.siteSpaces.find(predicate) ?? null;
108145
if (siteSpace) {
109-
return siteSpace;
146+
return { siteSpace, siteSection };
110147
}
111148
}
112149

113150
return null;
114151
}
115152

116-
function findSiteSpaceByIdInSiteSpaces(siteSpaces: SiteSpace[], spaceId: string): SiteSpace | null {
117-
return siteSpaces.find((siteSpace) => siteSpace.space.id === spaceId) ?? null;
153+
function findSiteSpaceByIdInSiteSpaces(
154+
siteSpaces: SiteSpace[],
155+
predicate: (siteSpace: SiteSpace) => boolean
156+
): SiteSpace | null {
157+
return siteSpaces.find(predicate) ?? null;
118158
}

0 commit comments

Comments
 (0)