feat(new-webui): Add card to Ingestion page showing time range, file count, and message count.#830
Conversation
WalkthroughThis update introduces several new React components for the IngestPage Details section, including Changes
Sequence Diagram(s)Error: Could not generate a valid Mermaid diagram after multiple attempts. Suggested reviewers
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (6)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (5)
⏰ Context from checks skipped due to timeout of 90000ms (2)
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (13)
components/log-viewer-webui/client/src/pages/IngestPage/SpaceSavings/index.module.css (1)
1-5: Consider using CSS variables for colours.While the implementation works well, consider using CSS variables or theme tokens for colours like #1888fa to make future theming changes (like dark mode) easier to implement.
components/log-viewer-webui/client/src/pages/IngestPage/Details/index.module.css (1)
19-23: Consider using theme colours instead of hardcoded values.Use theme variables or CSS variables for the colour "grey" to maintain consistency with the design system and make future theming changes easier.
components/log-viewer-webui/client/src/pages/IngestPage/index.tsx (1)
6-10: Enhance JSDoc comment.The JSDoc comment could be more detailed about the component's purpose and functionality. Consider expanding it to describe what compression statistics are shown and how they're structured on the page.
components/log-viewer-webui/client/src/pages/IngestPage/Details/Files.tsx (1)
22-30: Simplify conditional className pattern.The pattern
className={styles["card"] || ""}is used to handle potential undefined classes, but this is unnecessary with CSS modules as they handle undefined classes gracefully. Consider simplifying:- <Card className={styles["card"] || ""}> + <Card className={styles.card}> <div className={styles["cardContent"]}> - <Text className={styles["title"] || ""}> + <Text className={styles.title}> Files </Text> - <Text className={styles["statistic"] || ""}> + <Text className={styles.statistic}> {DUMMY_FILES} </Text> </div>This pattern should be applied consistently across all components that use CSS modules.
components/log-viewer-webui/client/src/pages/IngestPage/Details/TimeRange.tsx (3)
19-23: Add a proper return type to the JSDocThe JSDoc comment is missing a return type after the @return tag. Including a return type improves documentation clarity.
/** * Renders the time range statistic. * - * @return + * @return {JSX.Element} The rendered TimeRange component */
26-36: Remove redundant fallback for CSS class namesThe
|| ""fallback for style classes is unnecessary when using TypeScript with CSS modules, as TypeScript should enforce that these properties exist in the styles object.- <Card className={styles["card"] || ""}> + <Card className={styles["card"]}> <div className={styles["cardContent"]}> - <Text className={styles["title"] || ""}> + <Text className={styles["title"]}> Time Range </Text> - <Text className={styles["statistic"] || ""}> + <Text className={styles["statistic"]}> {`${dayjs(DUMMY_START_DATE).format(DATE_FORMAT)} - ${ dayjs(DUMMY_END_DATE).format(DATE_FORMAT) }`} </Text>
12-15: Consider adding type safety for date variablesWhile using dummy data for now, it would be beneficial to define types for these date variables to ensure they're used correctly when implementing the API integration.
// eslint-disable-next-line no-warning-comments // TODO: Replace with values from database once api implemented. -const DUMMY_START_DATE = "2021-12-14"; -const DUMMY_END_DATE = "2025-04-16"; +const DUMMY_START_DATE: string = "2021-12-14"; +const DUMMY_END_DATE: string = "2025-04-16";components/log-viewer-webui/client/src/pages/IngestPage/Details/Messages.tsx (3)
15-19: Add a proper return type to the JSDocThe JSDoc comment is missing a return type after the @return tag. Including a return type improves documentation clarity.
/** * Renders the messages statistic. * - * @return + * @return {JSX.Element} The rendered Messages component */
22-30: Remove redundant fallback for CSS class namesThe
|| ""fallback for style classes is unnecessary when using TypeScript with CSS modules, as TypeScript should enforce that these properties exist in the styles object.- <Card className={styles["card"] || ""}> + <Card className={styles["card"]}> <div className={styles["cardContent"]}> - <Text className={styles["title"] || ""}> + <Text className={styles["title"]}> Messages </Text> - <Text className={styles["statistic"] || ""}> + <Text className={styles["statistic"]}> {DUMMY_MESSAGES} </Text>
27-29: Add number formatting for better readabilityLarge numbers like 1,235,844 should be formatted with commas or other locale-appropriate separators for improved readability.
<Text className={styles["statistic"] || ""}> - {DUMMY_MESSAGES} + {DUMMY_MESSAGES.toLocaleString()} </Text>components/log-viewer-webui/client/src/pages/IngestPage/Details/index.tsx (1)
7-11: Add a proper return type to the JSDoc and improve component descriptionThe JSDoc comment is missing a return type after the @return tag, and the description could be more specific about what "details" are being presented.
/** - * Presents details from the given statistics. + * Presents a grid layout of statistics including time range, message count, and file count. * - * @return + * @return {JSX.Element} The rendered Details component */components/log-viewer-webui/client/src/pages/IngestPage/SpaceSavings/index.tsx (2)
16-20: Add a proper return type to the JSDocThe JSDoc comment is missing a return type after the @return tag. Including a return type improves documentation clarity.
/** * Presents space savings or compression ratio from the given statistics. * - * @return + * @return {JSX.Element} The rendered SpaceSavings component */
31-44: Remove redundant fallback for CSS class namesThe
|| ""fallback for style classes is unnecessary when using TypeScript with CSS modules, as TypeScript should enforce that these properties exist in the styles object.<Card - className={styles["card"] || ""} + className={styles["card"]} hoverable={true} > <div className={styles["cardContent"]}> - <Text className={styles["title"] || ""}> + <Text className={styles["title"]}> Space Savings </Text> - <Text className={styles["statistic"] || ""}> + <Text className={styles["statistic"]}> {spaceSavingsPercent.toFixed(2)} % </Text>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
components/log-viewer-webui/client/src/pages/IngestPage.tsx(0 hunks)components/log-viewer-webui/client/src/pages/IngestPage/Details/Files.tsx(1 hunks)components/log-viewer-webui/client/src/pages/IngestPage/Details/Messages.tsx(1 hunks)components/log-viewer-webui/client/src/pages/IngestPage/Details/TimeRange.tsx(1 hunks)components/log-viewer-webui/client/src/pages/IngestPage/Details/index.module.css(1 hunks)components/log-viewer-webui/client/src/pages/IngestPage/Details/index.tsx(1 hunks)components/log-viewer-webui/client/src/pages/IngestPage/SpaceSavings/index.module.css(1 hunks)components/log-viewer-webui/client/src/pages/IngestPage/SpaceSavings/index.tsx(1 hunks)components/log-viewer-webui/client/src/pages/IngestPage/index.module.css(1 hunks)components/log-viewer-webui/client/src/pages/IngestPage/index.tsx(1 hunks)
💤 Files with no reviewable changes (1)
- components/log-viewer-webui/client/src/pages/IngestPage.tsx
🧰 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}: - Preferfalse == <expression>rather than!<expression>.
components/log-viewer-webui/client/src/pages/IngestPage/Details/Files.tsxcomponents/log-viewer-webui/client/src/pages/IngestPage/index.tsxcomponents/log-viewer-webui/client/src/pages/IngestPage/Details/TimeRange.tsxcomponents/log-viewer-webui/client/src/pages/IngestPage/Details/index.tsxcomponents/log-viewer-webui/client/src/pages/IngestPage/Details/Messages.tsxcomponents/log-viewer-webui/client/src/pages/IngestPage/SpaceSavings/index.tsx
🧬 Code Graph Analysis (1)
components/log-viewer-webui/client/src/pages/IngestPage/SpaceSavings/index.tsx (2)
components/webui/imports/ui/IngestView/panels/SpaceSavings.jsx (1)
SpaceSavings(19-71)components/webui/imports/ui/IngestView/panels/IngestionJobs/IngestionJobRow.jsx (2)
compressedSize(57-57)uncompressedSize(52-52)
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: lint-check (macos-latest)
- GitHub Check: lint-check (ubuntu-latest)
🔇 Additional comments (6)
components/log-viewer-webui/client/src/pages/IngestPage/index.module.css (1)
1-6: Grid layout implementation looks good.The CSS Grid implementation provides a responsive layout that adapts well to different screen sizes. The use of
auto-fitwithminmaxcreates a fluid layout that will reflow as needed. The padding and gap provide appropriate spacing between elements.components/log-viewer-webui/client/src/pages/IngestPage/SpaceSavings/index.module.css (2)
7-9: Global selector usage is appropriate.The use of the
:global()selector to remove the border from Ant Design's card header is correct and follows best practices for CSS modules.
11-25: Typography styling looks good.The styling for card content, title, and statistic are well-defined and maintain a consistent visual hierarchy. The large font size (100px) for the statistic will ensure it has visual prominence on the page.
components/log-viewer-webui/client/src/pages/IngestPage/Details/index.module.css (1)
25-34: Nested grid implementation is well structured.The nested grid layout for details provides a clean way to organize the child components. The span configuration for timeRange ensures it takes the full width while other items share the available space.
components/log-viewer-webui/client/src/pages/IngestPage/Details/Files.tsx (1)
11-13: Dummy data and TODO comment are appropriate.The explicit TODO comment and use of a constant for dummy data make it clear that this is placeholder content waiting for API implementation. The eslint-disable comment is also properly scoped to just the TODO line.
components/log-viewer-webui/client/src/pages/IngestPage/Details/index.tsx (1)
12-22: The grid layout implementation looks goodThe implementation aligns with the PR objective of reverting to native grid layout instead of using Ant Design grid components. The structure is clean and will work well for responsive layouts.
| // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition | ||
| const spaceSavingsPercent = 0 < compressedSize ? | ||
| 100 * (1 - (compressedSize / uncompressedSize)) : | ||
| 0; |
There was a problem hiding this comment.
Add validation for uncompressedSize to prevent division by zero
There's a check for compressedSize > 0, but no check for uncompressedSize > 0. If uncompressedSize is 0, it will cause a division by zero error.
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
- const spaceSavingsPercent = 0 < compressedSize ?
- 100 * (1 - (compressedSize / uncompressedSize)) :
+ const spaceSavingsPercent = (0 < compressedSize && 0 < uncompressedSize) ?
+ 100 * (1 - (compressedSize / uncompressedSize)) :
0;📝 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.
| // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition | |
| const spaceSavingsPercent = 0 < compressedSize ? | |
| 100 * (1 - (compressedSize / uncompressedSize)) : | |
| 0; | |
| // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition | |
| const spaceSavingsPercent = (0 < compressedSize && 0 < uncompressedSize) ? | |
| 100 * (1 - (compressedSize / uncompressedSize)) : | |
| 0; |
🛠️ Refactor suggestion
Add validation for compression ratio
Currently, there's no validation that compressedSize <= uncompressedSize. If compressedSize > uncompressedSize, the percentage will be negative, which doesn't make sense for space savings.
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
- const spaceSavingsPercent = 0 < compressedSize ?
- 100 * (1 - (compressedSize / uncompressedSize)) :
- 0;
+ let spaceSavingsPercent = 0;
+ if (0 < compressedSize && 0 < uncompressedSize) {
+ // Ensure compressed size is not greater than uncompressed size
+ if (compressedSize <= uncompressedSize) {
+ spaceSavingsPercent = 100 * (1 - (compressedSize / uncompressedSize));
+ } else {
+ // Log an error or handle unexpected data
+ console.error("Compressed size is greater than uncompressed size");
+ }
+ }📝 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.
| // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition | |
| const spaceSavingsPercent = 0 < compressedSize ? | |
| 100 * (1 - (compressedSize / uncompressedSize)) : | |
| 0; | |
| // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition | |
| let spaceSavingsPercent = 0; | |
| if (0 < compressedSize && 0 < uncompressedSize) { | |
| // Ensure compressed size is not greater than uncompressed size | |
| if (compressedSize <= uncompressedSize) { | |
| spaceSavingsPercent = 100 * (1 - (compressedSize / uncompressedSize)); | |
| } else { | |
| // Log an error or handle unexpected data | |
| console.error("Compressed size is greater than uncompressed size"); | |
| } | |
| } |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (5)
components/log-viewer-webui/client/src/pages/IngestPage/Details/Files.tsx (1)
1-26: Clean implementation of the Files statistics card componentThe component is well-structured and follows React best practices. The TODO comment is properly marked with an eslint-disable directive, acknowledging the temporary nature of the hardcoded value.
Consider formatting the statistics value with appropriate separators (like commas or spaces) for better readability, especially when real data is implemented.
- stat={DUMMY_FILES.toString()} + stat={DUMMY_FILES.toLocaleString()}components/log-viewer-webui/client/src/pages/IngestPage/Details/Messages.tsx (1)
1-26: Clean implementation with room for localization improvementThe component is well-structured and follows React best practices. The TODO comment is properly documented with an eslint-disable directive.
For large numbers like 1,235,844, consider using number formatting for better readability of the statistics.
- stat={DUMMY_MESSAGES.toString()} + stat={DUMMY_MESSAGES.toLocaleString()}components/log-viewer-webui/client/src/components/DashboardCard/index.tsx (1)
48-50: Consider using named exports consistentlyThe component is exported using a named export, but from the usage in StatCard, it seems like it might be intended as the default export for the module.
Either change other imports to use named imports or consider exporting this as the default:
- export {DashboardCard}; + export default DashboardCard; + export {DashboardCard};components/log-viewer-webui/client/src/components/StatCard/index.tsx (2)
40-48: Simplify props spread object constructionThe current approach with conditional spreads works but can be simplified for better readability.
- const props: DashboardCardProps = { - title, - ...(titleColor ? - {titleColor} : - {}), - ...(backgroundColor ? - {backgroundColor} : - {}), - }; + const props: DashboardCardProps = { + title, + ...(titleColor && { titleColor }), + ...(backgroundColor && { backgroundColor }) + };
52-54: Consider handling default values for statSize and statColorThe component doesn't handle the case where statSize or statColor are undefined, which could lead to inconsistent styling if these props aren't provided.
- <Text style={{color: statColor, fontSize: statSize}}> + <Text style={{ + color: statColor || 'inherit', + fontSize: statSize || 'inherit' + }}>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
components/log-viewer-webui/client/src/components/DashboardCard/index.module.css(1 hunks)components/log-viewer-webui/client/src/components/DashboardCard/index.tsx(1 hunks)components/log-viewer-webui/client/src/components/StatCard/index.module.css(0 hunks)components/log-viewer-webui/client/src/components/StatCard/index.tsx(1 hunks)components/log-viewer-webui/client/src/pages/IngestPage/Details/Files.tsx(1 hunks)components/log-viewer-webui/client/src/pages/IngestPage/Details/Messages.tsx(1 hunks)components/log-viewer-webui/client/src/pages/IngestPage/Details/TimeRange.tsx(1 hunks)components/log-viewer-webui/client/src/pages/IngestPage/Details/index.module.css(1 hunks)components/log-viewer-webui/client/src/pages/IngestPage/SpaceSavings/index.tsx(3 hunks)components/log-viewer-webui/client/src/pages/IngestPage/index.tsx(2 hunks)
💤 Files with no reviewable changes (1)
- components/log-viewer-webui/client/src/components/StatCard/index.module.css
✅ Files skipped from review due to trivial changes (1)
- components/log-viewer-webui/client/src/components/DashboardCard/index.module.css
🚧 Files skipped from review as they are similar to previous changes (4)
- components/log-viewer-webui/client/src/pages/IngestPage/SpaceSavings/index.tsx
- components/log-viewer-webui/client/src/pages/IngestPage/index.tsx
- components/log-viewer-webui/client/src/pages/IngestPage/Details/index.module.css
- components/log-viewer-webui/client/src/pages/IngestPage/Details/TimeRange.tsx
🧰 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}: - Preferfalse == <expression>rather than!<expression>.
components/log-viewer-webui/client/src/components/DashboardCard/index.tsxcomponents/log-viewer-webui/client/src/pages/IngestPage/Details/Messages.tsxcomponents/log-viewer-webui/client/src/pages/IngestPage/Details/Files.tsxcomponents/log-viewer-webui/client/src/components/StatCard/index.tsx
| className={styles["title"] || ""} | ||
| style={{color: titleColor}} |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Improve fallback pattern for CSS class names
Same issue as with the card class - the logical OR fallback may not work as expected with CSS modules.
- className={styles["title"] || ""}
+ className={styles.title ?? ""}📝 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.
| className={styles["title"] || ""} | |
| style={{color: titleColor}} | |
| className={styles.title ?? ""} | |
| style={{ color: titleColor }} |
| className={styles["card"] || ""} | ||
| hoverable={true} |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Improve fallback pattern for CSS class names
The current fallback pattern using logical OR (||) may not work as expected with CSS modules. When styles["card"] is an empty string (but defined), it will still be used instead of falling back to the empty string.
- className={styles["card"] || ""}
+ className={styles.card ?? ""}📝 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.
| className={styles["card"] || ""} | |
| hoverable={true} | |
| className={styles.card ?? ""} | |
| hoverable={true} |
|
@junhaoliao - this is ready for review |
junhaoliao
left a comment
There was a problem hiding this comment.
it's great in terms of aesthetics. i'll approve once we confirm the extraction of DashboardCard from StatCard is necessary.
There was a problem hiding this comment.
What's the reason we want to extract this component from the StatCard component?
There was a problem hiding this comment.
We might have cards with a graph instead of a statistic. I thought having an empty card component was better, and then anything we want for content added as children
|
For the PR title, how about |
…count, and message count. (y-scope#830)
…count, and message count. (y-scope#830)
Description
Add card with time range, files, and messages to ingest page.
Goes back to native grid to due lack of features in antd grid.
Checklist
breaking change.
Validation performed
Checked resizing grid.
Summary by CodeRabbit
New Features
Refactor
Style