Skip to content

Commit a18baca

Browse files
committed
docs: update CUSTOMIZATIONS.md — all changes verified working as of 2026-04-28
customizations 1-8 implemented and verified: - #1 live tail feature flag + configurable duration - #2 autocomplete top-N display (pagination removed) - hyperdxio#3 per-keystroke clickhouse prefix search + includes() filtering + configurable date range (NEXT_PUBLIC_AUTOCOMPLETE_DATE_RANGE_MS) - hyperdxio#4 privileged-user access gate for team settings - hyperdxio#5 standard otel sdk exporter for app self-telemetry - hyperdxio#6 google sso with domain auto-join; sso button above email/password form - hyperdxio#7 next-runtime-env standalone __ENV.js generation at container startup - hyperdxio#8 live tail configurable refresh interval (15m/30m/1h)
1 parent fcc18e3 commit a18baca

1 file changed

Lines changed: 71 additions & 12 deletions

File tree

CUSTOMIZATIONS.md

Lines changed: 71 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -105,19 +105,19 @@ const effectiveIsLive = isLive && IS_LIVE_TAIL_ENABLED;
105105

106106
---
107107

108-
### 2. Search bar autocomplete — configurable page size with pagination
108+
### 2. Search bar autocomplete — configurable top-N display
109109

110110
**Added**: 2026-04-27
111-
**Last verified**: 2026-04-27
111+
**Last verified**: 2026-04-28
112112
**Branch**: `abhiroop93/feat/hyperdx-upgrade`
113113

114-
**Intent**: The autocomplete dropdown was hardcoded to show a maximum of 10 suggestions with no way to see the rest. This change makes the per-page limit configurable via env var and adds prev/next pagination controls when the result set exceeds one page. Keyboard navigation (ArrowUp/Down) crosses page boundaries automatically.
114+
**Intent**: The autocomplete dropdown was hardcoded to show a maximum of 10 suggestions with no way to configure it. This change makes the visible limit configurable via env var. Pagination was considered but removed — the per-keystroke ClickHouse prefix search (customization #3) makes pagination unnecessary because the result set is already narrowed server-side. A "Showing Top N" label appears when results are trimmed.
115115

116116
#### Environment variables introduced
117117

118118
| Variable | Type | Default | Description |
119119
|---|---|---|---|
120-
| `NEXT_PUBLIC_AUTOCOMPLETE_SUGGESTIONS_LIMIT` | integer | `10` | Max suggestions shown per page in the autocomplete dropdown |
120+
| `NEXT_PUBLIC_AUTOCOMPLETE_SUGGESTIONS_LIMIT` | integer | `10` | Max suggestions shown in the autocomplete dropdown |
121121

122122
#### Files changed
123123

@@ -138,23 +138,37 @@ export const AUTOCOMPLETE_SUGGESTIONS_LIMIT =
138138

139139
##### `packages/app/src/components/SearchInput/AutocompleteInput.tsx`
140140

141-
Add pagination state, derive `pagedSuggestions`, add prev/next controls. See git diff for full implementation.
141+
- Removed `Fuse.js` — replaced with `opt.value.toLowerCase().includes(searchTerm.toLowerCase())` for client-side filtering of the ClickHouse result set
142+
- Removed all pagination state (`page`, `totalPages`, `pagedSuggestions`, prev/next buttons)
143+
- Renders `suggestedProperties.slice(0, pageSize)` directly with a "Showing Top N" hint when trimmed
144+
- Simplified ArrowUp/Down to navigate within `0..visibleSuggestions.length-1`
142145

143146
---
144147

145-
### 3. Search bar autocomplete — per-keystroke value filtering
148+
### 3. Search bar autocomplete — per-keystroke ClickHouse prefix search
146149

147150
**Added**: 2026-04-27
148-
**Last verified**: 2026-04-27
151+
**Last verified**: 2026-04-28
149152
**Branch**: `abhiroop93/feat/hyperdx-upgrade`
150153

151-
**Intent**: The autocomplete dropdown only triggered once when a field name was fully typed. Suggestions now narrow with every character entered in the value portion. Field detection and clearing both operate on the last quote-aware token so multi-token queries and quoted values with spaces are handled correctly. A minimum-character threshold prevents the dropdown from appearing on very short inputs.
154+
**Intent**: The original autocomplete fetched a fixed top-N values for a field once (e.g. all `ServiceName` values) and filtered client-side. This had two problems:
155+
1. If the target value wasn't among the top N fetched, it could never appear regardless of what the user typed.
156+
2. Filtering was done by Fuse.js with `threshold: 0`, which scored substring matches slightly above 0 due to the pattern/text length ratio, causing valid matches like `user-entity` inside `user-entity-service` to be dropped.
157+
158+
The fix uses two layers:
159+
- **ClickHouse-side**: Each debounced keystroke adds `WHERE field ILIKE 'prefix%'` to the `chartConfig` so React Query fires a new targeted query. This bypasses the top-N limit entirely for specific searches.
160+
- **Client-side**: After the ClickHouse result returns, `String.prototype.includes()` filters the result set for the dropdown display.
161+
162+
Field detection operates on the last quote-aware token so multi-token queries (`level:"info" ServiceName:"user`) and negation (`-ServiceName:"foo`) are handled correctly.
163+
164+
The hook also returns `keyValCompleteOptions` directly (not merged with `fieldCompleteOptions`) so field names never bleed into the value-completion dropdown.
152165

153166
#### Environment variables introduced
154167

155168
| Variable | Type | Default | Description |
156169
|---|---|---|---|
157-
| `NEXT_PUBLIC_AUTOCOMPLETE_MIN_CHARS` | integer (≥ 0) | `1` | Minimum characters in the value portion before suggestions appear |
170+
| `NEXT_PUBLIC_AUTOCOMPLETE_MIN_CHARS` | integer (≥ 0) | `1` | Minimum characters typed before suggestions appear / ClickHouse prefix query fires |
171+
| `NEXT_PUBLIC_AUTOCOMPLETE_DATE_RANGE_MS` | integer (ms) | `3600000` (1 h) | Time window for autocomplete ClickHouse queries. Smaller = faster scans. |
158172

159173
#### Files changed
160174

@@ -193,11 +207,56 @@ export const AUTOCOMPLETE_MIN_CHARS =
193207
Number.isFinite(_rawAutocompleteMinChars) && _rawAutocompleteMinChars >= 0
194208
? _rawAutocompleteMinChars
195209
: 1;
210+
211+
const _rawAutocompleteRange = parseInt(
212+
env('NEXT_PUBLIC_AUTOCOMPLETE_DATE_RANGE_MS') ?? '',
213+
10,
214+
);
215+
export const AUTOCOMPLETE_DATE_RANGE_MS =
216+
Number.isFinite(_rawAutocompleteRange) && _rawAutocompleteRange > 0
217+
? _rawAutocompleteRange
218+
: 3600000; // 1 hour default
196219
```
197220

198-
##### `packages/app/src/hooks/useAutoCompleteOptions.tsx` and `packages/app/src/components/SearchInput/AutocompleteInput.tsx`
221+
##### `packages/app/src/hooks/useAutoCompleteOptions.tsx`
222+
223+
Key changes:
199224

200-
Rework field-detection and `suggestedProperties` useMemo to use quote-aware tokenizer. See git diff for full implementation.
225+
1. **Field detection** — operates on the last quote-aware token via `getLastToken` + `stripNegation`. Supports `field:value` in-progress form, negation, and multi-token queries.
226+
227+
2. **Field clearing** — clears `searchField` when the last token no longer starts with the detected field name, so typing a second field correctly re-fetches for the new field.
228+
229+
3. **Debounced ClickHouse prefix filter** — extracts the value prefix from the typed input, debounces it 300ms, and adds it to `chartConfigs.where`:
230+
```typescript
231+
where: fieldPath ? `${fieldPath} ILIKE '${safePrefix}%'` : '',
232+
```
233+
React Query detects the changed `chartConfig` object and fires a new query. Single-quotes in the prefix are escaped to prevent SQL injection.
234+
235+
4. **Configurable date range**`dateRange` uses `AUTOCOMPLETE_DATE_RANGE_MS` instead of the hardcoded 12-hour window.
236+
237+
5. **Return value** — returns `keyValCompleteOptions` directly instead of `deduplicate2dArray([fieldCompleteOptions, keyValCompleteOptions])`. When `searchField` is active and `keyVals` are loaded, only formatted value pairs are returned (not field names). Falls back to `fieldCompleteOptions` when no field is detected or values are still loading.
238+
239+
##### `packages/app/src/components/SearchInput/AutocompleteInput.tsx`
240+
241+
Added `extractFuseSearchTerm` helper to extract the value portion from the in-progress token for client-side filtering:
242+
```typescript
243+
function extractFuseSearchTerm(token: string): string {
244+
const t = token.startsWith('-') ? token.slice(1) : token;
245+
const quoted = t.match(/^[^\s:]+:"([^"]*)"?$/);
246+
if (quoted) return quoted[1].replace(/\*/g, '');
247+
const unquoted = t.match(/^[^\s:]+:(.+)$/);
248+
if (unquoted) return unquoted[1].replace(/\*/g, '');
249+
return t.replace(/\*/g, '');
250+
}
251+
```
252+
253+
`suggestedProperties` filters using `includes()` instead of Fuse.js:
254+
```typescript
255+
const lower = searchTerm.toLowerCase();
256+
return (autocompleteOptions ?? []).filter(opt =>
257+
opt.value.toLowerCase().includes(lower),
258+
);
259+
```
201260

202261
---
203262

@@ -284,7 +343,7 @@ Gate Data tab, Query Settings tab, and edit/add controls with `useIsPrivilegedUs
284343
- `packages/api/src/utils/passport.ts` — register `GoogleStrategy`
285344
- `packages/api/src/routers/api/root.ts` — add `/login/google` and `/auth/google/callback` routes
286345
- `packages/app/src/config.ts` — add `GOOGLE_SSO_ENABLED`
287-
- `packages/app/src/AuthPage.tsx` — show SSO button; handle `domainNotAllowed` error
346+
- `packages/app/src/AuthPage.tsx` — show SSO button above the email/password form with a divider below it; handle `domainNotAllowed` error
288347

289348
---
290349

0 commit comments

Comments
 (0)