Skip to content

Commit 8e05af5

Browse files
fix: allow search where input to expand full width on smaller screens (#2037)
## Summary On smaller screens (e.g. half MacBook screen), the search WHERE input on the search page was shrinking to be unusably small. This happened because the WHERE input (`flex: 1 1 0%`, `min-width: 0`) competed with fixed-width siblings — the TimePicker (`w={350}`), optional live-tail interval select (80px, `flexShrink: 0`), and submit button (`flexShrink: 0`) — inside a non-wrapping flex row. **Fix:** `DBSearchPage.tsx`: - Added `wrap="wrap"` to the outer flex container so items can flow to the next line when space is insufficient - Set `minWidth="min(600px, 100%)"` on `SearchWhereInput` so it wraps to full width at 600px, while capping at 100% on very narrow viewports to prevent horizontal overflow - Grouped TimePicker, live tail select, and Run button in a flexible inner `Flex` (`flex: 0 1 500px`, `minWidth: 0`) so they wrap together and can shrink to fit - TimePicker sits in a `Box` with `minWidth: 100` so it compresses on narrow screens while live tail select and Run button keep their fixed sizes `TimePicker.tsx`: - Added `width` prop (defaults to `350` for backward compatibility) so the search page can pass `width="100%"` to make TimePicker fill its flexible container `SearchPage.ts` (E2E page object): - Fixed flaky tests by pressing Escape after filling the search input to dismiss the autocomplete suggestions dropdown before clicking the submit button **Behavior:** - **Wide screens**: WHERE input and controls share a row as before, TimePicker stays at 350px - **Narrow screens**: WHERE input takes full width on its own row; TimePicker compresses to fit alongside live tail select and Run button without overflow - **Very narrow screens (<600px viewport)**: Everything still fits without horizontal overflow ### How to test locally or on Vercel 1. Navigate to the Search page (`/search`) 2. Resize the browser window to be narrow (e.g. half of a MacBook screen, ~700px wide) 3. Verify the WHERE input expands to full width on its own row 4. Verify TimePicker, live tail select, and Run button all fit on the second row without horizontal overflow 5. Resize even narrower and verify TimePicker compresses while the Run button remains visible 6. At wider widths, verify the WHERE input and controls remain on the same row as before ### References - Linear Issue: HDX-3903 Linear Issue: [HDX-3903](https://linear.app/clickhouse/issue/HDX-3903/on-smaller-screens-on-the-search-page-the-search-where-input-shrinks) <div><a href="https://cursor.com/agents/bc-dbc6584f-4844-40c4-9649-66a94ef7b017"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-web-light.png"><img alt="Open in Web" width="114" height="28" src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a>&nbsp;<a href="https://cursor.com/background-agent?bcId=bc-dbc6584f-4844-40c4-9649-66a94ef7b017"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img alt="Open in Cursor" width="131" height="28" src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a>&nbsp;</div> Co-authored-by: Cursor Agent <199161495+cursoragent@users.noreply.github.com>
1 parent cf45ddd commit 8e05af5

4 files changed

Lines changed: 48 additions & 36 deletions

File tree

‎packages/app/src/DBSearchPage.tsx‎

Lines changed: 43 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1725,7 +1725,7 @@ function DBSearchPage() {
17251725
onClose={setNewSourceModalClosed}
17261726
onCreate={onNewSourceCreate}
17271727
/>
1728-
<Flex gap="sm" mt="sm" px="sm">
1728+
<Flex gap="sm" mt="sm" px="sm" wrap="wrap">
17291729
<SearchWhereInput
17301730
tableConnection={inputSourceTableConnection}
17311731
control={control}
@@ -1735,41 +1735,49 @@ function DBSearchPage() {
17351735
luceneQueryHistoryType={QUERY_LOCAL_STORAGE.SEARCH_LUCENE}
17361736
enableHotkey
17371737
data-testid="search-input"
1738+
minWidth="min(600px, 100%)"
17381739
/>
1739-
<TimePicker
1740-
data-testid="time-picker"
1741-
inputValue={displayedTimeInputValue}
1742-
setInputValue={setDisplayedTimeInputValue}
1743-
onSearch={onTimePickerSearch}
1744-
onRelativeSearch={onTimePickerRelativeSearch}
1745-
showLive={analysisMode === 'results'}
1746-
isLiveMode={isLive}
1747-
// Default to relative time mode if the user has made changes to interval and reloaded.
1748-
defaultRelativeTimeMode={
1749-
isLive && interval !== LIVE_TAIL_DURATION_MS
1750-
}
1751-
/>
1752-
{isLive && (
1753-
<Tooltip label="Live tail refresh interval">
1754-
<Box style={{ width: 80, minWidth: 80, flexShrink: 0 }}>
1755-
<Select
1756-
size="sm"
1757-
w="100%"
1758-
data={LIVE_TAIL_REFRESH_FREQUENCY_OPTIONS}
1759-
value={String(refreshFrequency)}
1760-
onChange={value =>
1761-
setRefreshFrequency(value ? parseInt(value, 10) : null)
1762-
}
1763-
allowDeselect={false}
1764-
comboboxProps={{
1765-
withinPortal: true,
1766-
zIndex: 1000,
1767-
}}
1768-
/>
1769-
</Box>
1770-
</Tooltip>
1771-
)}
1772-
<SearchSubmitButton isFormStateDirty={formState.isDirty} />
1740+
<Flex
1741+
gap="sm"
1742+
style={{ flex: '0 1 500px', minWidth: 0 }}
1743+
align="center"
1744+
>
1745+
<TimePicker
1746+
data-testid="time-picker"
1747+
inputValue={displayedTimeInputValue}
1748+
setInputValue={setDisplayedTimeInputValue}
1749+
onSearch={onTimePickerSearch}
1750+
onRelativeSearch={onTimePickerRelativeSearch}
1751+
showLive={analysisMode === 'results'}
1752+
isLiveMode={isLive}
1753+
// Default to relative time mode if the user has made changes to interval and reloaded.
1754+
defaultRelativeTimeMode={
1755+
isLive && interval !== LIVE_TAIL_DURATION_MS
1756+
}
1757+
width="100%"
1758+
/>
1759+
{isLive && (
1760+
<Tooltip label="Live tail refresh interval">
1761+
<Box style={{ width: 80, minWidth: 80, flexShrink: 0 }}>
1762+
<Select
1763+
size="sm"
1764+
w="100%"
1765+
data={LIVE_TAIL_REFRESH_FREQUENCY_OPTIONS}
1766+
value={String(refreshFrequency)}
1767+
onChange={value =>
1768+
setRefreshFrequency(value ? parseInt(value, 10) : null)
1769+
}
1770+
allowDeselect={false}
1771+
comboboxProps={{
1772+
withinPortal: true,
1773+
zIndex: 1000,
1774+
}}
1775+
/>
1776+
</Box>
1777+
</Tooltip>
1778+
)}
1779+
<SearchSubmitButton isFormStateDirty={formState.isDirty} />
1780+
</Flex>
17731781
</Flex>
17741782
</form>
17751783
{searchedConfig != null && searchedSource != null && (

‎packages/app/src/components/TimePicker/TimePicker.tsx‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ const TimePickerComponent = ({
7878
showLive = false,
7979
isLiveMode = false,
8080
defaultRelativeTimeMode = false,
81+
width = 350,
8182
}: {
8283
inputValue: string;
8384
setInputValue: (str: string) => any;
@@ -87,6 +88,7 @@ const TimePickerComponent = ({
8788
showLive?: boolean;
8889
isLiveMode?: boolean;
8990
defaultRelativeTimeMode?: boolean;
91+
width?: number | string;
9092
}) => {
9193
const {
9294
userPreferences: { timeFormat },
@@ -248,7 +250,7 @@ const TimePickerComponent = ({
248250
onClick={toggle}
249251
placeholder="Time Range"
250252
size="sm"
251-
w={350}
253+
w={width}
252254
onKeyDown={e => {
253255
if (e.key === 'Enter' && e.target instanceof HTMLInputElement) {
254256
onSubmit?.(e.target.value);

‎packages/app/tests/e2e/components/TimePickerComponent.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ export class TimePickerComponent {
7070
const isOpen = await this.pickerPopover.isVisible();
7171
if (isOpen) return;
7272
await this.page.waitForLoadState('networkidle');
73+
await this.page.keyboard.press('Escape');
7374
await this.pickerInput.click();
7475
await this.pickerPopover.waitFor({ state: 'visible', timeout: 5000 });
7576
}

‎packages/app/tests/e2e/page-objects/SearchPage.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ export class SearchPage {
112112
*/
113113
async performSearch(query: string) {
114114
await this.searchInput.fill(query);
115+
await this.page.keyboard.press('Escape');
115116
await this.searchButton.click();
116117
await this.page.waitForLoadState('networkidle');
117118
// Wait for new results to populate

0 commit comments

Comments
 (0)