Skip to content

Commit c42400e

Browse files
JonasBaclaude
andcommitted
ref(cmdk): Extract getLocationHref and isExternalLocation to shared locationUtils
Both commandPalette.tsx and modal.tsx contained identical copies of these helpers. Move them to a shared locationUtils.ts module to eliminate duplication. Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
1 parent ede8b41 commit c42400e

File tree

3 files changed

+24
-36
lines changed

3 files changed

+24
-36
lines changed

static/app/components/commandPalette/ui/commandPalette.tsx

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {mergeProps} from '@react-aria/utils';
77
import {Item} from '@react-stately/collections';
88
import {useTreeState} from '@react-stately/tree';
99
import {AnimatePresence, motion} from 'framer-motion';
10-
import type {LocationDescriptor} from 'history';
1110

1211
import errorIllustration from 'sentry-images/spot/computer-missing.svg';
1312

@@ -28,13 +27,13 @@ import {
2827
useCommandPaletteDispatch,
2928
useCommandPaletteState,
3029
} from 'sentry/components/commandPalette/ui/commandPaletteStateContext';
30+
import {isExternalLocation} from 'sentry/components/commandPalette/ui/locationUtils';
3131
import {useCommandPaletteAnalytics} from 'sentry/components/commandPalette/useCommandPaletteAnalytics';
3232
import {FeedbackButton} from 'sentry/components/feedbackButton/feedbackButton';
3333
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
3434
import {IconArrow, IconClose, IconLink, IconOpen, IconSearch} from 'sentry/icons';
3535
import {IconDefaultsProvider} from 'sentry/icons/useIconDefaults';
3636
import {t} from 'sentry/locale';
37-
import {locationDescriptorToTo} from 'sentry/utils/reactRouter6Compat/location';
3837
import {fzf} from 'sentry/utils/search/fzf';
3938
import type {Theme} from 'sentry/utils/theme';
4039
import {useDebouncedValue} from 'sentry/utils/useDebouncedValue';
@@ -43,22 +42,6 @@ const MotionButton = motion.create(Button);
4342
const MotionIconSearch = motion.create(IconSearch);
4443
const MotionContainer = motion.create(Container);
4544

46-
function getLocationHref(to: LocationDescriptor): string {
47-
const resolved = locationDescriptorToTo(to);
48-
49-
if (typeof resolved === 'string') {
50-
return resolved;
51-
}
52-
53-
return `${resolved.pathname ?? ''}${resolved.search ?? ''}${resolved.hash ?? ''}`;
54-
}
55-
56-
function isExternalLocation(to: LocationDescriptor): boolean {
57-
const currentUrl = new URL(window.location.href);
58-
const targetUrl = new URL(getLocationHref(to), currentUrl.href);
59-
return targetUrl.origin !== currentUrl.origin;
60-
}
61-
6245
function makeLeadingItemAnimation(theme: Theme) {
6346
return {
6447
initial: {scale: 0.95, opacity: 0},
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import type {LocationDescriptor} from 'history';
2+
3+
import {locationDescriptorToTo} from 'sentry/utils/reactRouter6Compat/location';
4+
5+
export function getLocationHref(to: LocationDescriptor): string {
6+
const resolved = locationDescriptorToTo(to);
7+
8+
if (typeof resolved === 'string') {
9+
return resolved;
10+
}
11+
12+
return `${resolved.pathname ?? ''}${resolved.search ?? ''}${resolved.hash ?? ''}`;
13+
}
14+
15+
export function isExternalLocation(to: LocationDescriptor): boolean {
16+
const currentUrl = new URL(window.location.href);
17+
const targetUrl = new URL(getLocationHref(to), currentUrl.href);
18+
return targetUrl.origin !== currentUrl.origin;
19+
}

static/app/components/commandPalette/ui/modal.tsx

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,19 @@
11
import {useCallback} from 'react';
22
import {css} from '@emotion/react';
3-
import type {LocationDescriptor} from 'history';
43

54
import type {ModalRenderProps} from 'sentry/actionCreators/modal';
65
import type {CMDKActionData} from 'sentry/components/commandPalette/ui/cmdk';
76
import type {CollectionTreeNode} from 'sentry/components/commandPalette/ui/collection';
87
import {CommandPalette} from 'sentry/components/commandPalette/ui/commandPalette';
98
import {GlobalCommandPaletteActions} from 'sentry/components/commandPalette/ui/commandPaletteGlobalActions';
10-
import {locationDescriptorToTo} from 'sentry/utils/reactRouter6Compat/location';
9+
import {
10+
getLocationHref,
11+
isExternalLocation,
12+
} from 'sentry/components/commandPalette/ui/locationUtils';
1113
import type {Theme} from 'sentry/utils/theme';
1214
import {normalizeUrl} from 'sentry/utils/url/normalizeUrl';
1315
import {useNavigate} from 'sentry/utils/useNavigate';
1416

15-
function getLocationHref(to: LocationDescriptor): string {
16-
const resolved = locationDescriptorToTo(to);
17-
18-
if (typeof resolved === 'string') {
19-
return resolved;
20-
}
21-
22-
return `${resolved.pathname ?? ''}${resolved.search ?? ''}${resolved.hash ?? ''}`;
23-
}
24-
25-
function isExternalLocation(to: LocationDescriptor): boolean {
26-
const currentUrl = new URL(window.location.href);
27-
const targetUrl = new URL(getLocationHref(to), currentUrl.href);
28-
return targetUrl.origin !== currentUrl.origin;
29-
}
30-
3117
export default function CommandPaletteModal({Body, closeModal}: ModalRenderProps) {
3218
const navigate = useNavigate();
3319

0 commit comments

Comments
 (0)