Skip to content

Commit 4b411ea

Browse files
committed
Move to urls page actions
1 parent 6815dd1 commit 4b411ea

File tree

3 files changed

+70
-69
lines changed

3 files changed

+70
-69
lines changed

packages/gitbook/src/components/PageActions/PageActions.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,17 +171,14 @@ export function ActionOpenInLLM(props: {
171171

172172
const providerLabel = provider === 'chatgpt' ? 'ChatGPT' : 'Claude';
173173

174-
// Remove the .md extension from the URL to avoid sending a bad request to the LLM.
175-
const urlWithoutExtension = url.replace(/\.md$/, '');
176-
177174
return (
178175
<PageActionWrapper
179176
type={type}
180177
icon={provider}
181178
label={tString(language, 'open_in', providerLabel)}
182179
shortLabel={providerLabel}
183180
description={tString(language, 'ai_chat_ask_about_page', providerLabel)}
184-
href={getLLMURL(provider, urlWithoutExtension, language)}
181+
href={getLLMURL(provider, url, language)}
185182
/>
186183
);
187184
}

packages/gitbook/src/components/PageActions/PageActionsDropdown.tsx

Lines changed: 30 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,22 @@ import {
1818
ActionViewAsPDF,
1919
} from './PageActions';
2020

21-
interface PageActionsDropdownProps {
22-
siteTitle: string;
23-
markdownPageURL: string;
24-
mcpURL?: string;
25-
pdfURL?: string;
26-
className?: string;
27-
actions: SiteCustomizationSettings['pageActions'];
21+
export type PageActionsDropdownURLs = {
22+
html: string;
23+
markdown: string;
24+
mcp?: string;
25+
pdf?: string;
2826
editOnGit?: {
2927
provider: GitSyncState['installationProvider'];
3028
url: string;
3129
};
30+
};
31+
32+
interface PageActionsDropdownProps {
33+
siteTitle: string;
34+
urls: PageActionsDropdownURLs;
35+
className?: string;
36+
actions: SiteCustomizationSettings['pageActions'];
3237
}
3338

3439
/**
@@ -75,7 +80,7 @@ export function PageActionsDropdown(props: PageActionsDropdownProps) {
7580
* Return the list of actions to show in the dropdown menu.
7681
*/
7782
function getPageDropdownActions(props: PageActionsDropdownProps): React.ReactNode[] {
78-
const { siteTitle, markdownPageURL, mcpURL, actions } = props;
83+
const { siteTitle, urls, actions } = props;
7984
const assistants = useAI().assistants.filter(
8085
(assistant) => assistant.ui === true && assistant.pageAction
8186
);
@@ -94,55 +99,45 @@ function getPageDropdownActions(props: PageActionsDropdownProps): React.ReactNod
9499
<DropdownMenuSeparator className="first:hidden" />
95100
<ActionCopyMarkdown
96101
isDefaultAction={!assistants.length}
97-
markdownPageURL={markdownPageURL}
102+
markdownPageURL={urls.markdown}
98103
type="dropdown-menu-item"
99104
/>
100-
<ActionViewAsMarkdown markdownPageURL={markdownPageURL} type="dropdown-menu-item" />
105+
<ActionViewAsMarkdown markdownPageURL={urls.markdown} type="dropdown-menu-item" />
101106
</React.Fragment>
102107
) : null,
103108

104109
actions.externalAI ? (
105110
<React.Fragment key="externalAI">
106111
<DropdownMenuSeparator className="first:hidden" />
107-
<ActionOpenInLLM
108-
provider="chatgpt"
109-
url={markdownPageURL}
110-
type="dropdown-menu-item"
111-
/>
112-
<ActionOpenInLLM
113-
provider="claude"
114-
url={markdownPageURL}
115-
type="dropdown-menu-item"
116-
/>
112+
<ActionOpenInLLM provider="chatgpt" url={urls.html} type="dropdown-menu-item" />
113+
<ActionOpenInLLM provider="claude" url={urls.html} type="dropdown-menu-item" />
117114
</React.Fragment>
118115
) : null,
119116

120-
actions.mcp && mcpURL ? (
117+
actions.mcp && urls.mcp ? (
121118
<React.Fragment key="mcp">
122119
<DropdownMenuSeparator className="first:hidden" />
123-
<ActionCopyMCPURL mcpURL={mcpURL} type="dropdown-menu-item" />
120+
<ActionCopyMCPURL mcpURL={urls.mcp} type="dropdown-menu-item" />
124121
<ActionOpenMCP
125122
provider="vscode"
126-
mcpURL={mcpURL}
123+
mcpURL={urls.mcp}
127124
siteTitle={siteTitle}
128125
type="dropdown-menu-item"
129126
/>
130127
</React.Fragment>
131128
) : null,
132129

133-
props.editOnGit || props.pdfURL ? (
130+
urls.editOnGit || urls.pdf ? (
134131
<React.Fragment key="editOnGit">
135132
<DropdownMenuSeparator className="first:hidden" />
136-
{props.editOnGit ? (
133+
{urls.editOnGit ? (
137134
<ActionOpenEditOnGit
138135
type="dropdown-menu-item"
139-
provider={props.editOnGit.provider}
140-
url={props.editOnGit.url}
136+
provider={urls.editOnGit.provider}
137+
url={urls.editOnGit.url}
141138
/>
142139
) : null}
143-
{props.pdfURL ? (
144-
<ActionViewAsPDF url={props.pdfURL} type="dropdown-menu-item" />
145-
) : null}
140+
{urls.pdf ? <ActionViewAsPDF url={urls.pdf} type="dropdown-menu-item" /> : null}
146141
</React.Fragment>
147142
) : null,
148143
].filter(Boolean);
@@ -152,7 +147,7 @@ function getPageDropdownActions(props: PageActionsDropdownProps): React.ReactNod
152147
* A default action shown as a quick-access button beside the dropdown menu
153148
*/
154149
function getPageDefaultAction(props: PageActionsDropdownProps) {
155-
const { markdownPageURL, actions } = props;
150+
const { urls, actions } = props;
156151
const assistants = useAI().assistants.filter(
157152
(assistant) => assistant.ui === true && assistant.pageAction
158153
);
@@ -162,12 +157,12 @@ function getPageDefaultAction(props: PageActionsDropdownProps) {
162157
return <ActionOpenAssistant assistant={assistant} type="button" />;
163158
}
164159

165-
if (props.editOnGit) {
160+
if (urls.editOnGit) {
166161
return (
167162
<ActionOpenEditOnGit
168163
type="button"
169-
provider={props.editOnGit.provider}
170-
url={props.editOnGit.url}
164+
provider={urls.editOnGit.provider}
165+
url={urls.editOnGit.url}
171166
/>
172167
);
173168
}
@@ -176,7 +171,7 @@ function getPageDefaultAction(props: PageActionsDropdownProps) {
176171
return (
177172
<ActionCopyMarkdown
178173
isDefaultAction={!assistant}
179-
markdownPageURL={markdownPageURL}
174+
markdownPageURL={urls.markdown}
180175
type="button"
181176
/>
182177
);

packages/gitbook/src/components/PageBody/PageHeader.tsx

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ import { type RevisionPageDocument, SiteVisibility } from '@gitbook/api';
55
import { Icon } from '@gitbook/icons';
66
import urlJoin from 'url-join';
77
import { getPDFURLSearchParams } from '../PDF';
8-
import { PageActionsDropdown } from '../PageActions/PageActionsDropdown';
8+
import {
9+
PageActionsDropdown,
10+
type PageActionsDropdownURLs,
11+
} from '../PageActions/PageActionsDropdown';
912
import { PageIcon } from '../PageIcon';
1013
import { StyledLink } from '../primitives';
1114

@@ -40,35 +43,7 @@ export async function PageHeader(props: {
4043
// Show page actions if *any* of the actions are enabled
4144
<PageActionsDropdown
4245
siteTitle={context.site.title}
43-
markdownPageURL={`${context.linker.toAbsoluteURL(context.linker.toPathInSpace(page.path))}.md`}
44-
editOnGit={
45-
context.customization.git.showEditLink &&
46-
context.space.gitSync?.url &&
47-
page.git
48-
? {
49-
provider: context.space?.gitSync?.installationProvider,
50-
url: urlJoin(context.space.gitSync.url, page.git.path),
51-
}
52-
: undefined
53-
}
54-
pdfURL={
55-
context.customization.pdf.enabled
56-
? context.linker.toPathInSpace(
57-
`~gitbook/pdf?${getPDFURLSearchParams({
58-
page: page.id,
59-
only: true,
60-
limit: 100,
61-
}).toString()}`
62-
)
63-
: undefined
64-
}
65-
mcpURL={
66-
context.site.visibility !== SiteVisibility.VisitorAuth
67-
? context.linker.toAbsoluteURL(
68-
context.linker.toPathInSpace('~gitbook/mcp')
69-
)
70-
: undefined
71-
}
46+
urls={getPageActionsURLs(context, page)}
7247
actions={context.customization.pageActions}
7348
className={tcls(
7449
'float-right ml-4 xl:max-2xl:page-api-block:mr-62',
@@ -146,3 +121,37 @@ export async function PageHeader(props: {
146121
</header>
147122
);
148123
}
124+
125+
/**
126+
* Return the URLs for the page actions.
127+
*/
128+
function getPageActionsURLs(
129+
context: GitBookSiteContext,
130+
page: RevisionPageDocument
131+
): PageActionsDropdownURLs {
132+
const pageURL = context.linker.toAbsoluteURL(context.linker.toPathInSpace(page.path));
133+
return {
134+
html: pageURL,
135+
markdown: `${pageURL}.md`,
136+
editOnGit:
137+
context.customization.git.showEditLink && context.space.gitSync?.url && page.git
138+
? {
139+
provider: context.space?.gitSync?.installationProvider,
140+
url: urlJoin(context.space.gitSync.url, page.git.path),
141+
}
142+
: undefined,
143+
pdf: context.customization.pdf.enabled
144+
? context.linker.toPathInSpace(
145+
`~gitbook/pdf?${getPDFURLSearchParams({
146+
page: page.id,
147+
only: true,
148+
limit: 100,
149+
}).toString()}`
150+
)
151+
: undefined,
152+
mcp:
153+
context.site.visibility !== SiteVisibility.VisitorAuth
154+
? context.linker.toAbsoluteURL(context.linker.toPathInSpace('~gitbook/mcp'))
155+
: undefined,
156+
};
157+
}

0 commit comments

Comments
 (0)