Skip to content

feat(new-webui): Integrate aggregation results into query timeline UI.#941

Merged
davemarco merged 61 commits into
y-scope:mainfrom
davemarco:serveTimeline
Jun 2, 2025
Merged

feat(new-webui): Integrate aggregation results into query timeline UI.#941
davemarco merged 61 commits into
y-scope:mainfrom
davemarco:serveTimeline

Conversation

@davemarco

@davemarco davemarco commented May 29, 2025

Copy link
Copy Markdown
Contributor

Description

Pr connects server to timeline UI.

There are some changes from old webUI in that the timeline is always visible. I think this looks better.

Checklist

  • The PR satisfies the contribution guidelines.
  • This is a breaking change and that has been indicated in the PR title, OR this isn't a
    breaking change.
  • Necessary docs have been updated, OR no docs need to be updated.

Validation performed

Tested query. Timeline rendered as expected

Summary by CodeRabbit

  • New Features

    • Timeline visualizations now display live aggregation data, updating dynamically with query results.
    • Timeline configuration is synchronized with the selected time range upon query submission.
    • Zooming on the timeline updates the time range and triggers new queries when appropriate.
  • Bug Fixes

    • Timeline input controls are now correctly disabled during active queries.
  • Refactor

    • Improved internal handling of time ranges and bucket calculations for greater accuracy and consistency.
    • Simplified time range representation using UTC-based timestamps and tuple formats.
  • Chores

    • Enhanced state management for timeline configuration to support more reliable updates.

@davemarco davemarco requested a review from a team as a code owner May 29, 2025 20:09
@coderabbitai

coderabbitai Bot commented May 29, 2025

Copy link
Copy Markdown
Contributor
## Walkthrough

This update refactors the timeline and aggregation logic in the log viewer web UI. It standardizes time range handling using Dayjs tuples, introduces a new hook for fetching aggregation results, synchronizes timeline configuration with queries, and updates the global search state to track and update timeline configuration independently.

## Changes

| File(s)                                                                                                   | Change Summary                                                                                                                                                                                                                             |
|-----------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| components/log-viewer-webui/client/src/components/ResultsTimeline/index.tsx                               | Changed `onTimelineZoom` parameter from custom type to `[Dayjs, Dayjs]` tuple; `timelineBuckets` is now non-nullable; updated zoom handler and removed null checks.                                  |
| components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/index.tsx      | Refactored to use live aggregation data via new hook; timeline config now based on current time range; zoom handler updates config and can trigger new query; improved input disabling logic.         |
| components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/useAggregationResults.ts | Added new hook to fetch aggregation results using current aggregation job ID and reactive cursor.                                                                                                    |
| components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/utils.ts       | Updated `computeTimelineConfig` to accept `[dayjs.Dayjs, dayjs.Dayjs]` and use UTC time calculations.                                                                                                |
| components/log-viewer-webui/client/src/pages/SearchPage/SearchState/index.tsx                             | Added `timelineConfig` and `updateTimelineConfig` to search state; initialized and updated timeline configuration in store.                                                                          |
| components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/SearchButton/SubmitButton.tsx       | Now synchronizes timeline configuration with query submission by recalculating and updating timeline config before submitting a query.                                                               |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant User
    participant SubmitButton
    participant SearchStore
    participant Timeline
    participant AggregationHook

    User->>SubmitButton: Click submit
    SubmitButton->>SearchStore: updateTimelineConfig(newConfig)
    SubmitButton->>SearchStore: submitQuery({ timeRangeBucketSizeMillis: newConfig.bucketDurationMillis })
    SearchStore->>AggregationHook: aggregationJobId updated
    AggregationHook->>Timeline: Fetch aggregation results
    Timeline->>User: Display updated timeline
sequenceDiagram
    participant User
    participant Timeline
    participant SearchStore
    participant AggregationHook

    User->>Timeline: Zooms timeline
    Timeline->>SearchStore: updateTimelineConfig(zoomedConfig)
    Timeline->>SearchStore: updateTimeRange(zoomedRange)
    alt If query string is not empty
        Timeline->>SearchStore: submitQuery()
    end
    SearchStore->>AggregationHook: aggregationJobId updated
    AggregationHook->>Timeline: Fetch new aggregation results
Loading

Possibly related PRs

Suggested reviewers

  • junhaoliao

<!-- walkthrough_end -->


---

<details>
<summary>📜 Recent review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: ASSERTIVE**
**Plan: Pro**


<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 9d4691e94c51c92d90f0e4c700e480d9ca8f724a and d56f0c11c09cce0582d14ada44e26ea6993b2fd2.

</details>

<details>
<summary>📒 Files selected for processing (1)</summary>

* `components/log-viewer-webui/client/src/pages/SearchPage/SearchState/index.tsx` (4 hunks)

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>📓 Path-based instructions (1)</summary>

<details>
<summary>`**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}`: - Prefer `false == <expression>` rather than `!<expression>`.</summary>

> `**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}`: - Prefer `false == <expression>` rather than `!<expression>`.

- `components/log-viewer-webui/client/src/pages/SearchPage/SearchState/index.tsx`

</details>

</details>

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (2)</summary>

* GitHub Check: lint-check (macos-latest)
* GitHub Check: lint-check (ubuntu-latest)

</details>

<details>
<summary>🔇 Additional comments (5)</summary><blockquote>

<details>
<summary>components/log-viewer-webui/client/src/pages/SearchPage/SearchState/index.tsx (5)</summary>

`4-4`: **LGTM! Clean import additions.**

The new imports for `TimelineConfig` and `computeTimelineConfig` are appropriately added and necessary for the timeline configuration functionality.



Also applies to: 10-10

---

`26-26`: **LGTM! Proper default state initialization.**

The timeline configuration is correctly initialized using the `computeTimelineConfig` function with the default time range, ensuring consistent state initialization.

---

`65-70`: **Excellent documentation and design decision.**

The comment clearly explains the intended behaviour - that `timelineConfig` should only be updated on query submission, not on range picker changes. This separation of concerns helps maintain clean state management and prevents unnecessary timeline updates.

---

`79-79`: **LGTM! Consistent interface extension.**

The `updateTimelineConfig` method follows the same naming and signature pattern as other updater methods in the interface.

---

`105-107`: **LGTM! Proper zustand implementation.**

The implementation follows the established pattern used by other updater methods in the store, using zustand's `set` function correctly.

</details>

</blockquote></details>

</details>
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->
<!-- finishing_touch_checkbox_start -->

<details open="true">
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=y-scope/clp&utm_content=941):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Explain this complex logic.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai explain this code block.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and explain its main purpose.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->

@davemarco davemarco requested a review from junhaoliao May 29, 2025 20:09

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🔭 Outside diff range comments (1)
components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/SearchButton/SubmitButton.tsx (1)

40-41: ⚠️ Potential issue

Add missing dependency to prevent stale closures.

The useCallback dependency array is missing updateTimelineConfig. This could lead to stale closures where the callback references an outdated version of the function.

    }, [queryString,
-        timeRange]);
+        timeRange,
+        updateTimelineConfig]);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between adddc28 and 13247d7.

📒 Files selected for processing (6)
  • components/log-viewer-webui/client/src/components/ResultsTimeline/index.tsx (3 hunks)
  • components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/SearchButton/SubmitButton.tsx (1 hunks)
  • components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/index.tsx (2 hunks)
  • components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/useAggregationResults.ts (1 hunks)
  • components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/utils.ts (2 hunks)
  • components/log-viewer-webui/client/src/pages/SearchPage/SearchState/index.tsx (5 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}`: - Prefer `false == ` rather than `!`.

**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}: - Prefer false == <expression> rather than !<expression>.

  • components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/index.tsx
  • components/log-viewer-webui/client/src/components/ResultsTimeline/index.tsx
  • components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/utils.ts
  • components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/SearchButton/SubmitButton.tsx
  • components/log-viewer-webui/client/src/pages/SearchPage/SearchState/index.tsx
  • components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/useAggregationResults.ts
🧬 Code Graph Analysis (4)
components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/index.tsx (6)
components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/useAggregationResults.ts (1)
  • useAggregationResults (32-32)
components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/utils.ts (1)
  • computeTimelineConfig (95-95)
components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/utils.tsx (1)
  • TIME_RANGE_OPTION (70-70)
components/log-viewer-webui/client/src/pages/SearchPage/SearchState/index.tsx (1)
  • SEARCH_STATE_DEFAULT (102-102)
components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/search-requests.ts (1)
  • handleQuerySubmit (104-104)
components/log-viewer-webui/client/src/pages/SearchPage/SearchState/typings.ts (1)
  • SEARCH_UI_STATE (26-26)
components/log-viewer-webui/client/src/components/ResultsTimeline/index.tsx (2)
components/log-viewer-webui/client/src/components/ResultsTimeline/typings.ts (1)
  • TimelineBucket (28-28)
components/log-viewer-webui/client/src/components/ResultsTimeline/datetime/index.ts (1)
  • convertZoomTimestampToUtcDatetime (60-60)
components/log-viewer-webui/client/src/pages/SearchPage/SearchState/index.tsx (3)
components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/utils.ts (1)
  • computeTimelineConfig (95-95)
components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/utils.tsx (2)
  • TIME_RANGE_OPTION_DAYJS_MAP (71-71)
  • DEFAULT_TIME_RANGE (68-68)
components/log-viewer-webui/client/src/components/ResultsTimeline/typings.ts (1)
  • TimelineConfig (29-29)
components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/useAggregationResults.ts (3)
components/log-viewer-webui/client/src/api/socket/useCursor.tsx (1)
  • useCursor (79-79)
components/log-viewer-webui/client/src/components/ResultsTimeline/typings.ts (1)
  • TimelineBucket (28-28)
components/log-viewer-webui/client/src/pages/SearchPage/SearchState/index.tsx (1)
  • SEARCH_STATE_DEFAULT (102-102)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: lint-check (macos-latest)
🔇 Additional comments (13)
components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/SearchButton/SubmitButton.tsx (1)

29-36: Excellent integration of timeline configuration with query submission.

The synchronization of timeline configuration updates with query submission ensures consistency between the UI state and the submitted query parameters. The use of bucketDuration.asMilliseconds() for the bucket size is properly aligned with the timeline configuration.

components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/utils.ts (2)

3-3: Good addition of UTC plugin for consistent timezone handling.

The addition of the UTC plugin ensures all timeline calculations are performed in UTC, which is crucial for consistent time handling across different user timezones.

Also applies to: 11-11


44-48:

Details

✅ Verification successful

Verify function signature change is coordinated across the codebase.

The function signature change from separate Unix millisecond parameters to a Dayjs tuple is a breaking change. The implementation correctly converts the Dayjs objects to UTC milliseconds.


🏁 Script executed:

#!/bin/bash
# Description: Verify all callers of computeTimelineConfig have been updated to use the new signature.

# Test: Search for function calls to computeTimelineConfig. Expect: All calls use Dayjs tuple.
rg -A 3 "computeTimelineConfig\(" --type ts --type tsx

Length of output: 84


To ensure we catch all usages, let’s re-run the search without relying on ripgrep’s built-in file types:


🏁 Script executed:

#!/bin/bash
# Description: Find all calls to computeTimelineConfig in .ts and .tsx files
rg "computeTimelineConfig\(" -A 3 --glob '*.ts' --glob '*.tsx'

Length of output: 1732


All computeTimelineConfig callers updated to use the new Dayjs tuple signature

I’ve verified every usage of computeTimelineConfig across the codebase:

  • components/log-viewer-webui/client/src/pages/SearchPage/SearchState/index.tsx
  • components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/SearchButton/SubmitButton.tsx
  • components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/index.tsx

All call sites now pass a [Dayjs, Dayjs] tuple. No further changes needed.

components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/useAggregationResults.ts (1)

12-30: Well-implemented custom hook with proper patterns.

The hook correctly:

  • Uses the useCursor pattern for reactive data fetching
  • Handles the null case when no aggregation job is active
  • Includes proper dependency array with aggregationJobId
  • Returns a clear null or cursor result

The implementation follows React hooks best practices and integrates well with the existing architecture.

components/log-viewer-webui/client/src/components/ResultsTimeline/index.tsx (3)

46-47: Good API simplification and type consistency.

The changes to use Dayjs tuples instead of TimeRange objects and non-nullable timelineBuckets simplify the component API and align with the broader refactoring efforts.


176-178: Proper implementation of zoom callback with Dayjs tuple.

The zoom handler correctly creates a Dayjs tuple using convertZoomTimestampToUtcDatetime for consistent time handling, maintaining the UTC-based approach throughout the timeline system.


166-166: Excellent adherence to coding guidelines.

The boolean expression false === isInputDisabled correctly follows the project's coding guideline to prefer false == <expression> rather than !<expression>.

components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/index.tsx (3)

1-14: Import organization looks good.

The new imports are well-organized and necessary for the timeline integration functionality.


22-32: State management properly integrated.

Good use of the search store and aggregation results hook to get the necessary data and update functions.


60-66: Timeline data integration implemented correctly.

Good implementation:

  • Proper input disabling during query states
  • Safe fallback to empty array when aggregation results are not available
  • Correct prop passing to the ResultsTimeline component
components/log-viewer-webui/client/src/pages/SearchPage/SearchState/index.tsx (3)

11-27: Timeline configuration properly initialized.

Good implementation of the timeline config initialization using the computed value from the default time range. This ensures consistency between the time range and timeline configuration.


50-72: Excellent documentation and interface design.

The documentation clearly explains the purpose and update policy for timelineConfig. This helps maintain consistency by ensuring it's only updated during query submissions.


90-92: Update method correctly implemented.

Simple and effective implementation of the timeline config update method.

Comment on lines +47 to +53
handleQuerySubmit({
ignoreCase: false,
queryString: queryString,
timeRangeBucketSizeMillis: newTimelineConfig.bucketDuration.asMilliseconds(),
timestampBegin: newTimeRange[0].valueOf(),
timestampEnd: newTimeRange[1].valueOf(),
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Consider using the actual case sensitivity preference.

The ignoreCase parameter is hardcoded to false. If the search UI has a case sensitivity toggle, this should use the actual user preference from the search state.

Let me check if there's a case sensitivity setting in the search state:


🏁 Script executed:

#!/bin/bash
# Description: Check for case sensitivity settings in the search state and UI

# Search for ignoreCase or case sensitivity related state
rg -A 5 "ignoreCase|caseSensitive|caseInsensitive" --glob "**/*SearchState*" --glob "**/*Search*"

Length of output: 1987


Use actual case sensitivity preference for timeline zoom queries

The call to handleQuerySubmit in
components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/index.tsx (lines 47–53)
is hardcoding ignoreCase: false, which overrides the user’s case-sensitivity toggle in SearchView.jsx. To fix:

• Ensure this component receives the ignoreCase prop from the search state.
• Replace the hardcoded value with that prop when submitting the zoomed query.

Suggested diff:

--- a/components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/index.tsx
+++ b/components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/index.tsx
@@ 47,7
-       handleQuerySubmit({
-           ignoreCase: false,
+       handleQuerySubmit({
+           ignoreCase: ignoreCase,
            queryString: queryString,
            timeRangeBucketSizeMillis: newTimelineConfig.bucketDuration.asMilliseconds(),
            timestampBegin: newTimeRange[0].valueOf(),

This will align the timeline-zoom search with the UI’s case-sensitivity setting.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
handleQuerySubmit({
ignoreCase: false,
queryString: queryString,
timeRangeBucketSizeMillis: newTimelineConfig.bucketDuration.asMilliseconds(),
timestampBegin: newTimeRange[0].valueOf(),
timestampEnd: newTimeRange[1].valueOf(),
});
handleQuerySubmit({
ignoreCase: ignoreCase,
queryString: queryString,
timeRangeBucketSizeMillis: newTimelineConfig.bucketDuration.asMilliseconds(),
timestampBegin: newTimeRange[0].valueOf(),
timestampEnd: newTimeRange[1].valueOf(),
});
🤖 Prompt for AI Agents
In
components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/index.tsx
around lines 47 to 53, the ignoreCase parameter in handleQuerySubmit is
hardcoded to false, ignoring the user's case sensitivity preference. To fix
this, modify the component to accept the ignoreCase value from the search state
as a prop and replace the hardcoded false with this prop when calling
handleQuerySubmit, ensuring the timeline zoom queries respect the user's case
sensitivity setting.

Comment on lines +176 to +178
const newTimeRange: [Dayjs, Dayjs] =
[convertZoomTimestampToUtcDatetime(min),
convertZoomTimestampToUtcDatetime(max)];

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const newTimeRange: [Dayjs, Dayjs] =
[convertZoomTimestampToUtcDatetime(min),
convertZoomTimestampToUtcDatetime(max)];
const newTimeRange: [Dayjs, Dayjs] = [
convertZoomTimestampToUtcDatetime(min),
convertZoomTimestampToUtcDatetime(max)
];

*/
const SubmitButton = () => {
const {searchUiState, timeRange, queryString} = useSearchStore();
const {searchUiState, timeRange, queryString, updateTimelineConfig} = useSearchStore();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

purely stylish - we can address all in another PR

instead of retrieving the states / actions here, we can write

    const handleSubmitButtonClick = useCallback(() => {
        const {queryString, timeRange, updateTimelineConfig} = useSearchStore.get();
        // Update timeline to match range picker selection.
        const newTimelineConfig = computeTimelineConfig(timeRange);
        updateTimelineConfig(newTimelineConfig);

        handleQuerySubmit({
            ignoreCase: false,
            queryString: queryString,
            timeRangeBucketSizeMillis: newTimelineConfig.bucketDuration.asMilliseconds(),
            timestampBegin: timeRange[0].valueOf(),
            timestampEnd: timeRange[1].valueOf(),
        });
    }, []);

so the definition of handleSubmitButtonClick won't change at all

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

k i will do in later PR

const SubmitButton = () => {
const {searchUiState, timeRange, queryString} = useSearchStore();
const {searchUiState, timeRange, queryString, updateTimelineConfig} = useSearchStore();
const isQueryStringEmpty = queryString === SEARCH_STATE_DEFAULT.queryString;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's move this right above the return

* @return
*/
const SearchResultsTimeline = () => {
const {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto - see the Zustand state / action retrieval styling sugguestion

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will do this also in future PR

@junhaoliao junhaoliao left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for the title, how about

feat(new-webui): Integrate aggregation results into query timeline UI.

@davemarco davemarco changed the title feat(new-webui): Integrate aggregation results into timeline UI. feat(new-webui): Integrate aggregation results into query timeline UI. May 30, 2025
@davemarco davemarco requested a review from junhaoliao May 30, 2025 02:22

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ae8ebaa and 9215797.

📒 Files selected for processing (2)
  • components/log-viewer-webui/client/src/components/ResultsTimeline/index.tsx (3 hunks)
  • components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/SearchButton/SubmitButton.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}`: - Prefer `false == ` rather than `!`.

**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}: - Prefer false == <expression> rather than !<expression>.

  • components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/SearchButton/SubmitButton.tsx
  • components/log-viewer-webui/client/src/components/ResultsTimeline/index.tsx
🧬 Code Graph Analysis (2)
components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/SearchButton/SubmitButton.tsx (2)
components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/utils.ts (1)
  • computeTimelineConfig (95-95)
components/log-viewer-webui/client/src/pages/SearchPage/SearchState/index.tsx (1)
  • SEARCH_STATE_DEFAULT (101-101)
components/log-viewer-webui/client/src/components/ResultsTimeline/index.tsx (2)
components/log-viewer-webui/client/src/components/ResultsTimeline/typings.ts (1)
  • TimelineBucket (28-28)
components/log-viewer-webui/client/src/components/ResultsTimeline/datetime/index.ts (1)
  • convertZoomTimestampToUtcDatetime (60-60)
🪛 GitHub Actions: clp-lint
components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/SearchButton/SubmitButton.tsx

[error] 44-44: ESLint error: Trailing spaces not allowed (@stylistic/no-trailing-spaces).

components/log-viewer-webui/client/src/components/ResultsTimeline/index.tsx

[warning] 178-178: ESLint warning: Missing trailing comma (@stylistic/comma-dangle).

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: lint-check (macos-latest)
🔇 Additional comments (6)
components/log-viewer-webui/client/src/components/ResultsTimeline/index.tsx (2)

16-16: LGTM: Proper TypeScript type import.

Adding the explicit Dayjs type import is necessary for the type annotations used in the component props and improves type safety.


46-47: LGTM: Improved type safety and simplified API.

The changes standardize time range handling using [Dayjs, Dayjs] tuples and remove nullable handling for timelineBuckets. This simplifies the component interface and aligns with the broader refactoring effort described in the PR objectives.

components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/SearchButton/SubmitButton.tsx (4)

22-22: LGTM: Necessary store integration for timeline functionality.

Adding updateTimelineConfig to the destructured store variables enables the component to synchronize timeline configuration with query submission, which aligns with the PR objectives.


28-30: LGTM: Proper timeline configuration synchronization.

The implementation correctly computes and updates the timeline configuration before query submission, ensuring synchronization between the time range picker and timeline buckets. This aligns with the PR objectives to integrate aggregation results into the timeline UI.


35-35: LGTM: Consistent use of updated timeline configuration.

Using the bucket duration from the newly computed timeline configuration ensures the query submission parameters remain synchronized with the timeline settings.


39-41: LGTM: Correct dependency array update.

Adding updateTimelineConfig to the dependency array is necessary since it's now used within the callback, ensuring the callback updates correctly when the function reference changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants