Skip to content

Commit 3775726

Browse files
committed
feat: add clipboard keybinds to detail screens
- Add y keybind to copy resource name on all detail screens (via ResourceDetailPage) - Add h keybind to copy endpoint on MCP config detail screen (via extraKeybinds) - Enhanced clipboard feedback with descriptive labels (ID copied!, Name copied!, Endpoint copied!) - Add extraKeybinds/extraNavTips props to ResourceDetailPage for resource-specific shortcuts
1 parent 9a28f3e commit 3775726

3 files changed

Lines changed: 24 additions & 3 deletions

File tree

src/components/ResourceDetailPage.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ export function ResourceDetailPage<T>({
152152
onBack,
153153
buildDetailLines,
154154
additionalContent,
155+
extraKeybinds,
156+
extraNavTips,
155157
}: ResourceDetailPageProps<T>) {
156158
const isMounted = React.useRef(true);
157159
const { navigate } = useNavigation();
@@ -167,9 +169,9 @@ export function ResourceDetailPage<T>({
167169
const [copyStatus, setCopyStatus] = React.useState<string | null>(null);
168170

169171
// Copy to clipboard with status feedback
170-
const handleCopy = React.useCallback(async (text: string) => {
172+
const handleCopy = React.useCallback(async (text: string, label?: string) => {
171173
const status = await copyToClipboard(text);
172-
setCopyStatus(status);
174+
setCopyStatus(label ? `${label} copied!` : status);
173175
setTimeout(() => setCopyStatus(null), 2000);
174176
}, []);
175177

@@ -393,7 +395,8 @@ export function ResourceDetailPage<T>({
393395
bindings: {
394396
q: onBack,
395397
escape: onBack,
396-
c: () => handleCopy(getId(resource)),
398+
c: () => handleCopy(getId(resource), "ID"),
399+
y: () => handleCopy(getDisplayName(resource), "Name"),
397400
...(buildDetailLines
398401
? {
399402
i: () => {
@@ -411,6 +414,7 @@ export function ResourceDetailPage<T>({
411414
},
412415
enter: handleEnter,
413416
...(getUrl ? { o: handleOpenInBrowser } : {}),
417+
...(extraKeybinds ? extraKeybinds({ copy: handleCopy }) : {}),
414418
},
415419
onUnmatched: (input) => {
416420
// Operation shortcuts work from anywhere (all ops, including those in "View rest")
@@ -452,6 +456,8 @@ export function ResourceDetailPage<T>({
452456
operationsStartIndex,
453457
onOperation,
454458
getId,
459+
getDisplayName,
460+
extraKeybinds,
455461
],
456462
);
457463

@@ -808,6 +814,8 @@ export function ResourceDetailPage<T>({
808814
: "Execute",
809815
},
810816
{ key: "c", label: "Copy ID" },
817+
{ key: "y", label: "Copy Name" },
818+
...(extraNavTips || []),
811819
{ key: "i", label: "Full Details", condition: !!buildDetailLines },
812820
{ key: "o", label: "Browser", condition: !!getUrl },
813821
{ key: "q/Ctrl+C", label: "Back/Quit" },

src/components/resourceDetailTypes.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*/
44
import React from "react";
55
import type { ScreenName, RouteParams } from "../store/navigationStore.js";
6+
import type { NavigationTip } from "./NavigationTips.js";
67

78
// ---------------------------------------------------------------------------
89
// Detail field types
@@ -119,4 +120,10 @@ export interface ResourceDetailPageProps<T> {
119120
buildDetailLines?: (resource: T) => React.ReactElement[];
120121
/** Optional: Additional content to render after details section */
121122
additionalContent?: React.ReactNode;
123+
/** Optional: Extra keybinds added to the main view. Receives a copy helper for clipboard feedback. */
124+
extraKeybinds?: (helpers: {
125+
copy: (text: string, label?: string) => void;
126+
}) => Record<string, () => void>;
127+
/** Optional: Extra navigation tips shown in the footer alongside the standard ones */
128+
extraNavTips?: NavigationTip[];
122129
}

src/screens/McpConfigDetailScreen.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,12 @@ export function McpConfigDetailScreen({
368368
onOperation={handleOperation}
369369
onBack={goBack}
370370
buildDetailLines={buildDetailLines}
371+
extraKeybinds={({ copy }) => ({
372+
h: () => {
373+
copy(config.endpoint, "Endpoint");
374+
},
375+
})}
376+
extraNavTips={[{ key: "h", label: "Copy Endpoint" }]}
371377
/>
372378
);
373379
}

0 commit comments

Comments
 (0)