feat(webui): Move timestamp presets into AntD date picker. #1734
feat(webui): Move timestamp presets into AntD date picker. #1734davemarco merged 13 commits intoy-scope:mainfrom
Conversation
WalkthroughReplaces the Select-based preset UI with an Ant Design DatePicker.RangePicker and custom input; TimeDateInput now forwards native input events, accepts an isPickerOpen flag and reflects picker open state; adds a TimeRangePanel component and a minimal CSS module; removes prior CSS overrides for the input/picker. Changes
Sequence DiagramsequenceDiagram
actor User
participant TimeDateInput
participant RangePicker as DatePicker.RangePicker
participant TimeRangePanel
participant State as Time Range State
User->>TimeDateInput: click / focus input
TimeDateInput->>RangePicker: open picker
RangePicker->>TimeRangePanel: panelRender → mount panel
TimeRangePanel->>User: show preset options
alt User selects preset
User->>TimeRangePanel: click preset
TimeRangePanel->>State: updateTimeRange(preset → UTC range)
TimeRangePanel->>RangePicker: call onClose
RangePicker->>TimeDateInput: close picker
TimeDateInput->>User: display updated range
else User edits dates manually
User->>TimeDateInput: type/change input
TimeDateInput->>RangePicker: propagate change → handleRangePickerChange
RangePicker->>State: set option CUSTOM, normalize to UTC, updateTimeRange
State->>TimeDateInput: new range state
TimeDateInput->>User: show selected dates
end
User->>TimeDateInput: blur / click outside
TimeDateInput->>RangePicker: blur → close picker
RangePicker->>User: panel closed
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: ASSERTIVE Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used📓 Path-based instructions (1)**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}⚙️ CodeRabbit configuration file
Files:
🧬 Code graph analysis (1)components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/TimeRangePanel/index.tsx (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
🔇 Additional comments (3)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (5)
components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/TimeDateInput.tsx(2 hunks)components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/TimeRangePanel/index.module.css(1 hunks)components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/TimeRangePanel/index.tsx(1 hunks)components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/index.module.css(1 hunks)components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/index.tsx(4 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}
⚙️ CodeRabbit configuration file
- Prefer
false == <expression>rather than!<expression>.
Files:
components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/TimeRangePanel/index.tsxcomponents/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/TimeDateInput.tsxcomponents/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/index.tsx
🧠 Learnings (3)
📚 Learning: 2025-05-29T20:33:40.653Z
Learnt from: junhaoliao
Repo: y-scope/clp PR: 937
File: components/log-viewer-webui/client/src/AntdApp.tsx:16-24
Timestamp: 2025-05-29T20:33:40.653Z
Learning: In components/log-viewer-webui React codebase: Return type annotations (like `: JSX.Element`) are unnecessary and not preferred for React components in JSX/TSX files.
Applied to files:
components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/TimeRangePanel/index.tsxcomponents/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/TimeDateInput.tsxcomponents/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/index.tsx
📚 Learning: 2025-07-18T20:00:50.288Z
Learnt from: hoophalab
Repo: y-scope/clp PR: 1108
File: components/webui/client/src/pages/SearchPage/SearchControls/Presto/SqlQueryInput/index.tsx:15-15
Timestamp: 2025-07-18T20:00:50.288Z
Learning: In the y-scope/clp React webui client codebase, for Zustand store usage: use `useStore.getState().method` for callbacks since the output is not reactive and doesn't need state as a dependency in the hook, and use `useStore((state) => state.property)` with proper selectors for reactive components that need to re-render when state changes.
Applied to files:
components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/index.tsx
📚 Learning: 2025-04-08T22:32:05.366Z
Learnt from: davemarco
Repo: y-scope/clp PR: 797
File: components/log-viewer-webui/client/src/components/Layout/MainLayout.tsx:2-5
Timestamp: 2025-04-08T22:32:05.366Z
Learning: In this codebase using React Router v7.4.1, components should be imported directly from "react-router" (e.g., `import { Link, Outlet } from "react-router";`) rather than from "react-router-dom" as was common in previous versions of React Router.
Applied to files:
components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/index.tsx
🧬 Code graph analysis (2)
components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/TimeDateInput.tsx (1)
components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/utils.tsx (4)
DATE_RANGE_PROP_KEY(197-197)DATE_RANGE_POSITION(196-196)TIME_RANGE_OPTION(202-202)TIME_RANGE_DISPLAY_TEXT_MAP(201-201)
components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/index.tsx (5)
components/webui/client/src/config/index.ts (1)
SETTINGS_QUERY_ENGINE(23-23)components/webui/common/src/config.ts (1)
CLP_QUERY_ENGINES(53-53)components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/utils.tsx (2)
isValidDateRange(200-200)TIME_RANGE_OPTION(202-202)components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/TimeDateInput.tsx (1)
TimeDateInputProps(65-65)components/webui/client/src/pages/SearchPage/SearchState/typings.ts (1)
SEARCH_UI_STATE(31-31)
🪛 Biome (2.1.2)
components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/TimeRangePanel/index.tsx
[error] 57-74: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.
Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.
(lint/a11y/useKeyWithClickEvents)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: package-image
🔇 Additional comments (5)
components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/TimeRangePanel/index.module.css (1)
1-18: LGTM!The CSS module defines clean, minimal styles for the panel layout. Dynamic styles (padding, hover states) are appropriately handled via inline styles using antd design tokens in the corresponding TSX file.
components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/index.module.css (1)
1-8: LGTM!The removal of Select-specific styling aligns well with the refactoring to DatePicker.RangePicker. The remaining styles appropriately support the new component structure.
components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/TimeDateInput.tsx (1)
23-52: LGTM!The event handling and display logic are well-implemented. The component correctly switches to CUSTOM mode when the user manually edits the input, and the display text appropriately shows preset labels when closed and actual values when the picker is open or in CUSTOM mode.
components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/index.tsx (2)
40-92: LGTM!The state management and callback handlers are well-implemented. The automatic switch to CUSTOM mode when users manually change dates (line 54) is a good UX decision. All
useCallbackdependencies are correctly specified, and the separation of concerns between panel rendering, input customization, and event handling is clean.
94-100: LGTM!The footer rendering logic correctly follows the coding guideline by using
false === isPrestoGuidedrather than!isPrestoGuided.
...nts/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/TimeRangePanel/index.tsx
Show resolved
Hide resolved
...nts/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/TimeRangePanel/index.tsx
Show resolved
Hide resolved
...nts/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/TimeRangePanel/index.tsx
Outdated
Show resolved
Hide resolved
hoophalab
left a comment
There was a problem hiding this comment.
LGTM. two nitpicks
Validation: clicking presets changes the selected time range.
| onMouseEnter={(e) => { | ||
| e.currentTarget.style.backgroundColor = token.controlItemBgHover; | ||
| }} | ||
| onMouseLeave={(e) => { | ||
| e.currentTarget.style.backgroundColor = "transparent"; | ||
| }} |
There was a problem hiding this comment.
This part isn't reactive. I guess you've tried having a backgroundColor state and use that state in style={{...}}? There is a short delay?
There was a problem hiding this comment.
this is doing the hover effect. and u cant put on hover in style {}. I would put in css file, but then u cant use antD token
There was a problem hiding this comment.
i may not understand what u mean by your comment
There was a problem hiding this comment.
Sorry, I didn't make myself clear. How about this:
@@ -9,6 +9,7 @@ import {
TIME_RANGE_OPTION_NAMES,
} from "../utils";
import styles from "./index.module.css";
+import {Nullable} from "@webui/common/utility-types";
interface TimeRangePanelProps {
@@ -42,6 +43,8 @@ const TimeRangePanel = ({panelNode, onClose}: TimeRangePanelProps) => {
});
};
+ const [activeOption, setActiveOption] = React.useState<Nullable<string>>(null);
+
return (
<div className={styles["panelContainer"]}>
<ul
@@ -61,15 +64,13 @@ const TimeRangePanel = ({panelNode, onClose}: TimeRangePanelProps) => {
borderRadius: token.borderRadiusSM,
paddingInline: token.paddingXS,
paddingBlock: token.paddingXXS,
+ backgroundColor: option === activeOption ? token.controlItemBgHover : "transparent"
}}
onClick={() => {
handlePresetClick(option);
}}
onMouseEnter={(e) => {
- e.currentTarget.style.backgroundColor = token.controlItemBgHover;
- }}
- onMouseLeave={(e) => {
- e.currentTarget.style.backgroundColor = "transparent";
+ setActiveOption(option);
}}
>
{option}
There was a problem hiding this comment.
might need to set option as null when mouse leaves
| value={displayText}/> | ||
| {...restProps} | ||
| value={displayText} | ||
| onBlur={handleBlur} |
There was a problem hiding this comment.
Can we pass onblur and onfocus directly to input through restprops? This way we don't need the two handle.* delegates
There was a problem hiding this comment.
Actionable comments posted: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/TimeDateInput.tsx(2 hunks)components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/index.tsx(4 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}
⚙️ CodeRabbit configuration file
- Prefer
false == <expression>rather than!<expression>.
Files:
components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/TimeDateInput.tsxcomponents/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/index.tsx
🧠 Learnings (3)
📚 Learning: 2025-05-29T20:33:40.653Z
Learnt from: junhaoliao
Repo: y-scope/clp PR: 937
File: components/log-viewer-webui/client/src/AntdApp.tsx:16-24
Timestamp: 2025-05-29T20:33:40.653Z
Learning: In components/log-viewer-webui React codebase: Return type annotations (like `: JSX.Element`) are unnecessary and not preferred for React components in JSX/TSX files.
Applied to files:
components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/TimeDateInput.tsxcomponents/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/index.tsx
📚 Learning: 2025-07-18T20:00:50.288Z
Learnt from: hoophalab
Repo: y-scope/clp PR: 1108
File: components/webui/client/src/pages/SearchPage/SearchControls/Presto/SqlQueryInput/index.tsx:15-15
Timestamp: 2025-07-18T20:00:50.288Z
Learning: In the y-scope/clp React webui client codebase, for Zustand store usage: use `useStore.getState().method` for callbacks since the output is not reactive and doesn't need state as a dependency in the hook, and use `useStore((state) => state.property)` with proper selectors for reactive components that need to re-render when state changes.
Applied to files:
components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/index.tsx
📚 Learning: 2025-04-08T22:32:05.366Z
Learnt from: davemarco
Repo: y-scope/clp PR: 797
File: components/log-viewer-webui/client/src/components/Layout/MainLayout.tsx:2-5
Timestamp: 2025-04-08T22:32:05.366Z
Learning: In this codebase using React Router v7.4.1, components should be imported directly from "react-router" (e.g., `import { Link, Outlet } from "react-router";`) rather than from "react-router-dom" as was common in previous versions of React Router.
Applied to files:
components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/index.tsx
🧬 Code graph analysis (1)
components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/TimeDateInput.tsx (1)
components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/utils.tsx (4)
DATE_RANGE_PROP_KEY(197-197)DATE_RANGE_POSITION(196-196)TIME_RANGE_OPTION(202-202)TIME_RANGE_DISPLAY_TEXT_MAP(201-201)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: package-image
- GitHub Check: build (ubuntu-24.04)
- GitHub Check: build (macos-15)
🔇 Additional comments (2)
components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/TimeDateInput.tsx (1)
23-48: LGTM! Props are now correctly forwarded via rest spread.The implementation properly addresses the previous review feedback by spreading
restPropsto passonBlur,onFocus, and other native input attributes directly to the underlying<input>element. The display logic correctly shows the actual value when the picker is open or in custom mode, restoring the preset label otherwise.components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/index.tsx (1)
82-92: LGTM! Custom panel and input component integration.The
panelRenderandinputComponentcallbacks are correctly memoized with appropriate dependencies. TheinputComponentpattern properly injectsisPickerOpenstate intoTimeDateInput, enabling the display logic to show actual values when the picker is open per the PR objectives.
components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/index.tsx
Show resolved
Hide resolved
components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/index.tsx
Outdated
Show resolved
Hide resolved
|
@hoophalab i realized i could use antd menu instead of custom list. From their docs looks like menu is for navigation, but turns out u can use anywhere. So it handles hover. I also changed it to keep highlight when selected preset, so it is a bit fancier |
hoophalab
left a comment
There was a problem hiding this comment.
LGTM. much cleaner than before!
junhaoliao
left a comment
There was a problem hiding this comment.
deferring to @hoophalab 's review
Description
Moves presets into the Ant Design time selector.
AntD’s built-in presets feature couldn’t be used properly because it automatically triggers the onChange callback and isn’t asynchronous. Triggering onChange is problematic here — we use that callback to update the picker value when switching to a custom timestamp, but we don’t want it to fire when selecting a preset, since in that case we just want to display the preset label instead of the raw date/time values.
Implementation Details
To fix this, I rendered a fully custom preset component next to the AntD date picker. This prevents unwanted onChange triggers and supports asynchronous behavior.
When the user opens the picker, it shows the current timestamp value. I tried keeping the preset text visible inside the picker, but it made editing timestamps awkward and complicated the code. If the user doesn’t make any changes and simply closes the picker, the preset text reappears.
Checklist
breaking change.
Validation performed
Presets change
Summary by CodeRabbit
New Features
Improvements
✏️ Tip: You can customize this high-level summary in your review settings.