Skip to content

Commit df69496

Browse files
authored
Merge pull request #36575 from github/repo-sync
Repo sync
2 parents 82c08e5 + 348b46b commit df69496

File tree

9 files changed

+63
-29
lines changed

9 files changed

+63
-29
lines changed

Diff for: src/events/components/experiments/experiment.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ export function shouldShowExperiment(
5454
? routerQuery.feature.toLowerCase() === experiment.turnOnWithURLParam.toLowerCase()
5555
: false
5656
) {
57-
controlGroupOverride[experimentKey] = TREATMENT_VARIATION
5857
return true
5958
}
6059
}
@@ -115,6 +114,15 @@ export function getExperimentVariationForContext(locale: string, version: string
115114
const experiments = getActiveExperiments(locale, version)
116115
for (const experiment of experiments) {
117116
if (experiment.includeVariationInContext) {
117+
// If the user is using the URL param to view the experiment, include the variation in the context
118+
if (
119+
experiment.turnOnWithURLParam &&
120+
window.location?.search
121+
?.toLowerCase()
122+
.includes(`feature=${experiment.turnOnWithURLParam.toLowerCase()}`)
123+
) {
124+
return TREATMENT_VARIATION
125+
}
118126
return getExperimentControlGroupFromSession(
119127
experiment.key,
120128
experiment.percentOfUsersToGetExperiment,

Diff for: src/frame/middleware/handle-next-data-path.ts

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import type { Response, NextFunction } from 'express'
2+
import statsd from '@/observability/lib/statsd.js'
23

34
import type { ExtendedRequest } from '@/types.js'
45

6+
const STATSD_KEY = 'middleware.handle_next_data_path'
7+
58
export default function handleNextDataPath(
69
req: ExtendedRequest,
710
res: Response,
@@ -12,7 +15,16 @@ export default function handleNextDataPath(
1215
// this is triggered via client-side route transitions
1316
// example path:
1417
// /_next/data/development/en/free-pro-team%40latest/github/setting-up-and-managing-your-github-user-account.json
15-
const decodedPath = decodeURIComponent(req.path)
18+
let decodedPath = ''
19+
try {
20+
decodedPath = decodeURIComponent(req.path)
21+
} catch {
22+
res.status(400).send(`Bad request`)
23+
const tags = ['response:400', `path:${req.path}`]
24+
statsd.increment(STATSD_KEY, 1, tags)
25+
return
26+
}
27+
1628
const parts = decodedPath.split('/').slice(4)
1729
// free-pro-team@latest should not be included in the page path
1830
if (parts[1] === 'free-pro-team@latest') {

Diff for: src/search/components/input/AskAIResults.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ export function AskAIResults({
320320
<ActionList.Item
321321
sx={{
322322
marginLeft: '0px',
323+
paddingLeft: '0px',
323324
}}
324325
key={`reference-${index}`}
325326
tabIndex={-1}

Diff for: src/search/components/input/SearchBarButton.module.scss

+2-2
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,8 @@
160160
.searchIconContainer svg {
161161
overflow: visible !important;
162162

163-
width: 16;
164-
height: 16;
163+
width: 16px;
164+
height: 16px;
165165

166166
fill: currentColor;
167167
color: var(--fgColor-muted, var(--color-fg-muted, #656d76));

Diff for: src/search/components/input/SearchBarButton.tsx

+8-2
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,17 @@ export function SearchBarButton({ isSearchOpen, setIsSearchOpen }: Props) {
7171
aria-hidden
7272
tabIndex={-1}
7373
>
74-
<CopilotIcon aria-hidden className="mr-1" />
7574
<span
7675
className={cx(styles.queryText, !urlSearchInputQuery ? styles.placeholder : null)}
7776
>
78-
{urlSearchInputQuery ? urlSearchInputQuery : t('search.input.placeholder')}
77+
{urlSearchInputQuery ? (
78+
urlSearchInputQuery
79+
) : (
80+
<>
81+
{t('search.input.placeholder')}
82+
<CopilotIcon aria-hidden className="mr-1 ml-1" />
83+
</>
84+
)}
7985
</span>
8086
</div>
8187
<span className={styles.searchIconContainer} aria-hidden tabIndex={-1}>

Diff for: src/search/components/input/SearchOverlay.tsx

+26-20
Original file line numberDiff line numberDiff line change
@@ -240,13 +240,10 @@ export function SearchOverlay({
240240
event.preventDefault()
241241
const newQuery = event.target.value
242242
setSelectedIndex(-1) // Reset selected index when query changes
243-
// We don't need to fetch autocomplete results when asking the AI
244-
if (!isAskAIState || aiSearchError || aiCouldNotAnswer) {
245-
setSearchLoading(true)
246-
updateAutocompleteResults(newQuery)
247-
}
248-
// If the query empties while we are in the AI state, we should switch back to the search state
249-
if (isAskAIState && newQuery.trim() === '') {
243+
// Whenever the query changes, we want to leave the Ask AI state
244+
setSearchLoading(true)
245+
updateAutocompleteResults(newQuery)
246+
if (isAskAIState) {
250247
updateParams({
251248
'search-overlay-ask-ai': '',
252249
'search-overlay-input': newQuery,
@@ -296,6 +293,7 @@ export function SearchOverlay({
296293
'search-overlay-ask-ai': 'true',
297294
'search-overlay-input': selectedOption.term,
298295
})
296+
setSearchLoading(true)
299297
setAIQuery(selectedOption.term)
300298
inputRef.current?.focus()
301299
}
@@ -464,7 +462,6 @@ export function SearchOverlay({
464462
<ActionList
465463
aria-label={t('search.overlay.suggestions_list_aria_label')}
466464
showDividers
467-
selectionVariant="single"
468465
className={styles.suggestionsList}
469466
ref={suggestionsListHeightRef}
470467
>
@@ -526,22 +523,12 @@ export function SearchOverlay({
526523
selectedIndex,
527524
listElementsRef,
528525
askAIState,
526+
searchLoading,
527+
previousSuggestionsListHeight,
529528
)}
530529
</ActionList>
531530
</>
532531
)
533-
} else if (searchLoading) {
534-
OverlayContents = (
535-
<Box
536-
role="status"
537-
className={styles.loadingContainer}
538-
sx={{
539-
height: `${previousSuggestionsListHeight}px`,
540-
}}
541-
>
542-
<Spinner />
543-
</Box>
544-
)
545532
} else {
546533
OverlayContents = (
547534
<ActionList
@@ -560,6 +547,8 @@ export function SearchOverlay({
560547
selectedIndex,
561548
listElementsRef,
562549
askAIState,
550+
searchLoading,
551+
previousSuggestionsListHeight,
563552
)}
564553
</ActionList>
565554
)
@@ -701,6 +690,8 @@ function renderSearchGroups(
701690
aiCouldNotAnswer: boolean
702691
setAICouldNotAnswer: (value: boolean) => void
703692
},
693+
searchLoading: boolean,
694+
previousSuggestionsListHeight: number | string,
704695
) {
705696
const groups = []
706697

@@ -744,6 +735,21 @@ function renderSearchGroups(
744735
groups.push(<ActionList.Divider key="general-divider" />)
745736
}
746737

738+
if (searchLoading) {
739+
groups.push(
740+
<Box
741+
role="status"
742+
className={styles.loadingContainer}
743+
sx={{
744+
height: `${previousSuggestionsListHeight}px`,
745+
}}
746+
>
747+
<Spinner />
748+
</Box>,
749+
)
750+
return groups
751+
}
752+
747753
// We want to show general search suggestions underneath the AI Response section if the AI Could no answer
748754
if ((generalSearchOptions.length && !isInAskAIState) || isInAskAIStateButNoAnswer) {
749755
const items = []

Diff for: src/search/components/input/variables.scss

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Widths of the search bar button at different breakpoints
22
$smHeaderSearchInputWidth: 100%; // Technically we don't show the search bar at this breakpoint
33
$mdHeaderSearchInputWidth: 100%; // Technically we don't show the search bar at this breakpoint
4-
$lgHeaderSearchInputWidth: 30rem;
4+
$lgHeaderSearchInputWidth: 25rem;
55
$xlHeaderSearchInputWidth: 40rem;
66

77
// Widths of the search overlay popup at different breakpoints

Diff for: src/shielding/middleware/handle-invalid-nextjs-paths.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ export default function handleInvalidNextPaths(
1818
// In local dev, we don't get these penetration-testing looking requests.
1919
if (
2020
process.env.NODE_ENV !== 'development' &&
21-
req.path.startsWith('/_next/') &&
22-
!req.path.startsWith('/_next/data')
21+
((req.path.startsWith('/_next/') && !req.path.startsWith('/_next/data')) ||
22+
req.query?.['__nextFallback'])
2323
) {
2424
defaultCacheControl(res)
2525

Diff for: src/shielding/middleware/handle-invalid-query-strings.ts

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const MAX_UNFAMILIAR_KEYS_REDIRECT = 3
1313
const RECOGNIZED_KEYS_BY_PREFIX = {
1414
'/_next/data/': ['versionId', 'productId', 'restPage', 'apiVersion', 'category', 'subcategory'],
1515
'/api/search': ['query', 'language', 'version', 'page', 'product', 'autocomplete', 'limit'],
16+
'/api/combined-search': ['query', 'version', 'size', 'debug'],
1617
'/api/anchor-redirect': ['hash', 'path'],
1718
'/api/webhooks': ['category', 'version'],
1819
'/api/pageinfo': ['pathname'],

0 commit comments

Comments
 (0)