1- import { Fragment , useCallback } from 'react' ;
1+ import { Fragment } from 'react' ;
22
33import { render , screen , userEvent , waitFor } from 'sentry-test/reactTestingLibrary' ;
44
@@ -24,47 +24,18 @@ jest.mock('@tanstack/react-virtual', () => ({
2424
2525import { closeModal } from 'sentry/actionCreators/modal' ;
2626import * as modalActions from 'sentry/actionCreators/modal' ;
27- import { CommandPaletteProvider } from 'sentry/components/commandPalette/ui/cmdk' ;
28- import { CMDKAction } from 'sentry/components/commandPalette/ui/cmdk' ;
29- import type { CMDKActionData } from 'sentry/components/commandPalette/ui/cmdk' ;
30- import type { CollectionTreeNode } from 'sentry/components/commandPalette/ui/collection ' ;
27+ import {
28+ CMDKAction ,
29+ CommandPaletteProvider ,
30+ } from 'sentry/components/commandPalette/ui/cmdk ' ;
3131import { CommandPalette } from 'sentry/components/commandPalette/ui/commandPalette' ;
3232import { CommandPaletteSlot } from 'sentry/components/commandPalette/ui/commandPaletteSlot' ;
33- import { useNavigate } from 'sentry/utils/useNavigate' ;
34-
35- function GlobalActionsComponent ( {
36- children,
37- onAction,
38- } : {
39- children ?: React . ReactNode ;
40- onAction ?: (
41- action : CollectionTreeNode < CMDKActionData > ,
42- options ?: { modifierKeys ?: { shiftKey : boolean } }
43- ) => void ;
44- } ) {
45- const navigate = useNavigate ( ) ;
46-
47- const handleAction = useCallback (
48- (
49- action : CollectionTreeNode < CMDKActionData > ,
50- options ?: { modifierKeys ?: { shiftKey : boolean } }
51- ) => {
52- if ( onAction ) {
53- onAction ( action , options ) ;
54- } else if ( 'to' in action ) {
55- navigate ( action . to ) ;
56- } else if ( 'onAction' in action ) {
57- action . onAction ( ) ;
58- }
59- closeModal ( ) ;
60- } ,
61- [ navigate , onAction ]
62- ) ;
6333
34+ function GlobalActionsComponent ( { children} : { children ?: React . ReactNode } ) {
6435 return (
6536 < CommandPaletteProvider >
6637 { children }
67- < CommandPalette onAction = { handleAction } />
38+ < CommandPalette closeModal = { closeModal } />
6839 </ CommandPaletteProvider >
6940 ) ;
7041}
@@ -118,23 +89,27 @@ describe('CommandPalette', () => {
11889 expect ( closeSpy ) . toHaveBeenCalledTimes ( 1 ) ;
11990 } ) ;
12091
121- it ( 'shift-enter on an internal link forwards modifier keys and closes modal' , async ( ) => {
92+ it ( 'shift-enter on an internal link opens in a new tab and closes modal' , async ( ) => {
12293 const closeSpy = jest . spyOn ( modalActions , 'closeModal' ) ;
123- const onAction = jest . fn ( ) ;
94+ const openSpy = jest . spyOn ( window , 'open' ) . mockReturnValue ( null ) ;
12495
12596 render (
126- < GlobalActionsComponent onAction = { onAction } >
97+ < GlobalActionsComponent >
12798 < CMDKAction to = "/target/" display = { { label : 'Go to route' } } />
12899 </ GlobalActionsComponent >
129100 ) ;
130101
131102 await screen . findByRole ( 'textbox' , { name : 'Search commands' } ) ;
132103 await userEvent . keyboard ( '{Shift>}{Enter}{/Shift}' ) ;
133104
134- expect ( onAction ) . toHaveBeenCalledWith ( expect . objectContaining ( { to : '/target/' } ) , {
135- modifierKeys : { shiftKey : true } ,
136- } ) ;
105+ expect ( openSpy ) . toHaveBeenCalledWith (
106+ expect . stringContaining ( 'target' ) ,
107+ '_blank' ,
108+ 'noreferrer'
109+ ) ;
137110 expect ( closeSpy ) . toHaveBeenCalledTimes ( 1 ) ;
111+
112+ openSpy . mockRestore ( ) ;
138113 } ) ;
139114
140115 it ( 'shows internal and external trailing link indicators for link actions' , async ( ) => {
@@ -398,18 +373,6 @@ describe('CommandPalette', () => {
398373 const secondaryCallback = jest . fn ( ) ;
399374 const closeSpy = jest . spyOn ( modalActions , 'closeModal' ) ;
400375
401- // Mirror the updated modal.tsx handleSelect: invoke callback, skip close when
402- // action has children so the palette can push into the secondary actions.
403- const handleAction = ( action : CollectionTreeNode < CMDKActionData > ) => {
404- if ( 'onAction' in action ) {
405- action . onAction ( ) ;
406- if ( action . children . length > 0 ) {
407- return ;
408- }
409- }
410- closeModal ( ) ;
411- } ;
412-
413376 // Top-level groups become section headers (disabled), so the action-with-callback
414377 // must be a child item — matching how "Parent Group Action" works in allActions.
415378 render (
@@ -422,7 +385,7 @@ describe('CommandPalette', () => {
422385 />
423386 </ CMDKAction >
424387 </ CMDKAction >
425- < CommandPalette onAction = { handleAction } />
388+ < CommandPalette closeModal = { closeModal } />
426389 </ CommandPaletteProvider >
427390 ) ;
428391
@@ -522,7 +485,7 @@ describe('CommandPalette', () => {
522485 < CommandPaletteSlot name = "task" >
523486 < CMDKAction display = { { label : 'Task Action' } } onAction = { jest . fn ( ) } />
524487 </ CommandPaletteSlot >
525- < CommandPalette onAction = { jest . fn ( ) } />
488+ < CommandPalette closeModal = { jest . fn ( ) } />
526489 </ CommandPaletteSlot . Provider >
527490 </ CommandPaletteProvider >
528491 ) ;
@@ -541,9 +504,7 @@ describe('CommandPalette', () => {
541504 < CommandPaletteSlot name = "task" >
542505 < CMDKAction display = { { label : 'Task Action' } } onAction = { onAction } />
543506 </ CommandPaletteSlot >
544- < CommandPalette
545- onAction = { node => ( 'onAction' in node ? node . onAction ( ) : null ) }
546- />
507+ < CommandPalette closeModal = { jest . fn ( ) } />
547508 </ CommandPaletteSlot . Provider >
548509 </ CommandPaletteProvider >
549510 ) ;
@@ -559,7 +520,7 @@ describe('CommandPalette', () => {
559520 < CommandPaletteSlot name = "page" >
560521 < CMDKAction display = { { label : 'Page Action' } } onAction = { jest . fn ( ) } />
561522 </ CommandPaletteSlot >
562- < CommandPalette onAction = { jest . fn ( ) } />
523+ < CommandPalette closeModal = { jest . fn ( ) } />
563524 </ CommandPaletteSlot . Provider >
564525 </ CommandPaletteProvider >
565526 ) ;
@@ -578,9 +539,7 @@ describe('CommandPalette', () => {
578539 < CommandPaletteSlot name = "page" >
579540 < CMDKAction display = { { label : 'Page Action' } } onAction = { onAction } />
580541 </ CommandPaletteSlot >
581- < CommandPalette
582- onAction = { node => ( 'onAction' in node ? node . onAction ( ) : null ) }
583- />
542+ < CommandPalette closeModal = { jest . fn ( ) } />
584543 </ CommandPaletteSlot . Provider >
585544 </ CommandPaletteProvider >
586545 ) ;
@@ -606,7 +565,7 @@ describe('CommandPalette', () => {
606565 < CommandPaletteSlot name = "page" >
607566 < CMDKAction display = { { label : 'Page Action' } } onAction = { jest . fn ( ) } />
608567 </ CommandPaletteSlot >
609- < CommandPalette onAction = { jest . fn ( ) } />
568+ < CommandPalette closeModal = { jest . fn ( ) } />
610569 </ CommandPaletteSlot . Provider >
611570 </ CommandPaletteProvider >
612571 ) ;
@@ -630,7 +589,7 @@ describe('CommandPalette', () => {
630589 < CommandPaletteSlot name = "task" >
631590 < CMDKAction display = { { label : 'Task Action' } } onAction = { jest . fn ( ) } />
632591 </ CommandPaletteSlot >
633- < CommandPalette onAction = { jest . fn ( ) } />
592+ < CommandPalette closeModal = { jest . fn ( ) } />
634593 </ CommandPaletteSlot . Provider >
635594 </ CommandPaletteProvider >
636595 ) ;
@@ -659,7 +618,7 @@ describe('CommandPalette', () => {
659618
660619 render (
661620 < CommandPaletteProvider >
662- < CommandPalette onAction = { jest . fn ( ) } >
621+ < CommandPalette closeModal = { jest . fn ( ) } >
663622 < ActionsViaGlobalSlot />
664623 </ CommandPalette >
665624 </ CommandPaletteProvider >
@@ -678,7 +637,7 @@ describe('CommandPalette', () => {
678637 < CommandPaletteProvider >
679638 < CMDKAction display = { { label : 'Empty Group' } } />
680639 < CMDKAction display = { { label : 'Real Action' } } onAction = { jest . fn ( ) } />
681- < CommandPalette onAction = { jest . fn ( ) } />
640+ < CommandPalette closeModal = { jest . fn ( ) } />
682641 </ CommandPaletteProvider >
683642 ) ;
684643
@@ -692,7 +651,7 @@ describe('CommandPalette', () => {
692651 render (
693652 < CommandPaletteProvider >
694653 < CMDKAction display = { { label : 'Direct Action' } } onAction = { jest . fn ( ) } />
695- < CommandPalette onAction = { jest . fn ( ) } />
654+ < CommandPalette closeModal = { jest . fn ( ) } />
696655 </ CommandPaletteProvider >
697656 ) ;
698657
0 commit comments