Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: No Incidents Message #1763

Merged
merged 4 commits into from
Feb 27, 2025

Conversation

Br0wnHammer
Copy link
Contributor

Describe your changes

This update modifies the incident display logic in the UI. It now conditionally renders the following:

  • For existing incidents: The original layout is displayed with the count of total checks and the timestamp of the hovered incident.
  • For "No incidents" scenario: A centered message saying "Great. No incidents, yet!" is shown.

[Have tested on Safari, Chrome & Firefox]

Issue number

#1757

Please ensure all items are checked off before requesting a review. "Checked off" means you need to add an "x" character between brackets so they turn into checkmarks.

  • (Do not skip this or your PR will be closed) I deployed the application locally.
  • (Do not skip this or your PR will be closed) I have performed a self-review and testing of my code.
  • I have included the issue # in the PR.
  • I have labelled the PR correctly.
  • The issue I am working on is assigned to me.
  • I didn't use any hardcoded values (otherwise it will not scale, and will make it difficult to maintain consistency across the application).
  • I made sure font sizes, color choices etc are all referenced from the theme.
  • My PR is granular and targeted to one specific feature.
  • I took a screenshot or a video and attached to this PR if there is a UI change.
Screenshot 2025-02-14 at 10 48 17 AM

Copy link

coderabbitai bot commented Feb 14, 2025

Walkthrough

This pull request introduces a new EmptyView component for displaying customizable empty state messages. The component supports several props for icon, header, message, size, and styling. Additionally, the ChartBox component has been modified to accept noDataMessage and isEmpty props. When isEmpty is true, the ChartBox renders the EmptyView instead of its standard chart content, ensuring an appropriate empty state is shown when there is no data.

Changes

File Change Summary
src/Components/Charts/ChartBox/EmptyView.jsx Added the new EmptyView component with customizable props (icon, header, message, heading level, justify content, height).
src/Components/Charts/ChartBox/index.jsx Updated ChartBox to include noDataMessage and isEmpty props; renders EmptyView when isEmpty is true.
src/Pages/Uptime/Details/Components/ChartBoxes/index.jsx Added isEmpty and noDataMessage props to ChartBox components for "Uptime" and "Incidents".

Possibly related PRs

  • Added fallback UI when there are no incidents recorded #600: The changes in the main PR, which introduce the EmptyView component for displaying an empty state, are related to the retrieved PR that adds a fallback UI for incidents, as both involve rendering specific UI components based on the absence of data.
  • fix: fe/pagespeed details empty view, resolves #1674 #1675: The changes in the main PR are related to the introduction of the EmptyView component, which is utilized in the ChartBox component to handle empty states, while the retrieved PR focuses on implementing an empty view for the PageSpeed details, indicating a similar purpose of displaying empty states in different contexts.

Suggested reviewers

  • ajhollid
  • gorkem-bwl
  • Skorpios604

📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3650a61 and cd1b304.

📒 Files selected for processing (1)
  • src/Components/Charts/ChartBox/EmptyView.jsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/Components/Charts/ChartBox/EmptyView.jsx

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • 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 generate unit testing code for this file.
    • @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 generate unit testing code.
    • @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.

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 for 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.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
Client/src/Pages/Uptime/Details/Components/ChartBoxes/index.jsx (2)

100-102: Yo, this condition's got some repetition, dawg! Let's clean it up!

Extract the reduce operation into a variable to avoid code duplication and improve readability.

+const totalDownChecks = monitor?.groupedDownChecks?.reduce(
+  (count, checkGroup) => count + checkGroup.totalChecks,
+  0
+) ?? 0;
+
-{hoveredIncidentsData !== null ||
-  (monitor?.groupedDownChecks?.reduce((count, checkGroup) => count + checkGroup.totalChecks, 0) > 0) ? (
+{hoveredIncidentsData !== null || totalDownChecks > 0 ? (

124-126: The message is straight fire, but let's make it translatable!

Consider using a translation system for the "No incidents" message to support internationalization.

-Great. No incidents, yet!
+{t('incidents.none')}
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f59eada and c5d50ff.

📒 Files selected for processing (1)
  • Client/src/Pages/Uptime/Details/Components/ChartBoxes/index.jsx (1 hunks)
🔇 Additional comments (1)
Client/src/Pages/Uptime/Details/Components/ChartBoxes/index.jsx (1)

100-128: This implementation is straight 🔥! Clean conditional rendering!

The logic for handling both incident and no-incident scenarios is well-structured and matches the PR objectives perfectly. The conditional rendering provides a clear user experience.

Copy link

@llamapreview llamapreview bot left a comment

Choose a reason for hiding this comment

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

Auto Pull Request Review from LlamaPReview

1. Overview

1.1 PR Summary

  • Business value and requirements alignment: The PR fixes an issue where no message was displayed when there were no incidents. It aligns with the business requirement of providing clear and concise information to users.
  • Key components modified: The incident display logic in the UI.
  • Impact assessment: The change will affect the user experience and visual representation of incidents.
  • System dependencies and integration impacts: The change interacts with the incident data and the UI components responsible for displaying this data.

1.2 Architecture Changes

  • System design modifications: None.
  • Component interactions: The change interacts with the incident data and the UI components responsible for displaying this data.
  • Integration points: None.

2. Detailed Technical Analysis

2.1 Code Logic Deep-Dive

Core Logic Changes

  • Client/src/Pages/Uptime/Details/Components/ChartBoxes/index.jsx - ChartBoxes
    • Submitted PR Code:
    {hoveredIncidentsData !== null ||
        (monitor?.groupedDownChecks?.reduce((count, checkGroup) => count + checkGroup.totalChecks, 0) > 0) ? (
        // Original layout for when incidents exist
        <Box position="relative">
            <Typography component="span">
                {hoveredIncidentsData !== null
                    ? hoveredIncidentsData.totalChecks
                    : monitor?.groupedDownChecks?.reduce((count, checkGroup) => count + checkGroup.totalChecks, 0)}
            </Typography>
            {hoveredIncidentsData !== null && hoveredIncidentsData.time !== null && (
                <Typography
                    component="h5"
                    position="absolute"
                    top="100%"
                    fontSize={11}
                    color={theme.palette.primary.contrastTextTertiary}
                >
                    {formatDateWithTz(hoveredIncidentsData._id, dateFormat, uiTimezone)}
                </Typography>
            )}
        </Box>
    ) : (
        // Centered layout for "No incidents" message
        <Box m="auto" marginY="25%">
            <Typography component="span">
                Great. No incidents, yet!
            </Typography>
        </Box>
    )}
  • Analysis:
    • The PR introduces conditional rendering based on the presence of incidents, which is a good approach for simplifying the UI and improving readability.
    • However, the current logic assumes that hoveredIncidentsData is always available. If it's null and there are no incidents, the component will throw an error when trying to access hoveredIncidentsData.totalChecks.
    • The edge case where hoveredIncidentsData is null and there are no incidents is not handled gracefully.
    • The formatDateWithTz function is called even when hoveredIncidentsData.time is null, which could lead to unexpected behavior or errors.
    • The "No incidents" message is hardcoded, which violates the "no hardcoded values" rule mentioned in the PR checklist.
  • LlamaPReview Suggested Improvements:
    {((hoveredIncidentsData?.totalChecks) !== undefined) ||
        (monitor?.groupedDownChecks?.reduce((count, checkGroup) => count + checkGroup.totalChecks, 0) > 0) ? (
        // Original layout for when incidents exist
        <Box position="relative">
            <Typography component="span">
                {(hoveredIncidentsData?.totalChecks) ?? monitor?.groupedDownChecks?.reduce((count, checkGroup) => count + checkGroup.totalChecks, 0)}
            </Typography>
            {hoveredIncidentsData?.time !== null && (
                <Typography
                    component="h5"
                    position="absolute"
                    top="100%"
                    fontSize={11}
                    color={theme.palette.primary.contrastTextTertiary}
                >
                    {formatDateWithTz(hoveredIncidentsData._id, dateFormat, uiTimezone)}
                </Typography>
            )}
        </Box>
    ) : (
        // Centered layout for "No incidents" message
        <Box m="auto" marginY="25%">
            <Typography component="span">
                {t('noIncidentsMessage')} {/* Use translation for the message */}
            </Typography>
        </Box>
    )}
  • Improvement rationale:
    • Using optional chaining (?.) prevents the component from throwing an error when trying to access a property that is null or undefined.
    • The undefined check ensures that the component does not throw an error when hoveredIncidentsData is null and there are no incidents.
    • Using translations for the "No incidents" message ensures that the message is consistent across the application and can be easily updated if needed.
    • The formatDateWithTz function is only called when hoveredIncidentsData.time is not null, preventing unexpected behavior or errors.

3. Critical Findings

Potential Issues
  • 🔴 Critical Issues

    • Issue: The current logic assumes that hoveredIncidentsData is always available, which can lead to errors if it's null and there are no incidents.
    • Impact: The component will throw an error, leading to unexpected behavior and a poor user experience.
    • Recommendation: Use optional chaining (?.) and an undefined check to prevent these errors.
  • 🟡 Warnings

    • Warning: The "No incidents" message is hardcoded, which violates the "no hardcoded values" rule mentioned in the PR checklist.
    • Potential risks: Inconsistencies in the UI and difficulty maintaining the application.
    • Suggested improvements: Use translations for the "No incidents" message to ensure consistency and ease of updates.

4. Security Assessment

Security Considerations
  • Authentication/Authorization impacts: None.
  • Data handling concerns: None.
  • Input validation: The change does not introduce any new input validation concerns.
  • Security best practices: The change aligns with security best practices.
  • Potential security risks: None identified.
  • Mitigation strategies: None required.
  • Security testing requirements: None identified.

5. Testing Strategy

Testing Recommendations
  • Test Coverage:

    • Unit test analysis: The change should be covered by unit tests to ensure that the conditional rendering logic works as expected.
    • Integration test requirements: Integration tests should validate that the change works correctly with the rest of the application.
    • Edge cases coverage: Tests should cover the edge case where hoveredIncidentsData is null and there are no incidents.
  • Test Recommendations:

    • Suggested Test Cases:
    it('should display the "No incidents" message when there are no incidents', () => {
      // Arrange
      const monitor = { groupedDownChecks: [] };
      const hoveredIncidentsData = null;
      const { getByText } = render(<ChartBoxes monitor={monitor} hoveredIncidentsData={hoveredIncidentsData} />);

      // Act & Assert
      expect(getByText('Great. No incidents, yet!')).toBeInTheDocument();
    });

    it('should not throw an error when hoveredIncidentsData is null and there are no incidents', () => {
      // Arrange
      const monitor = { groupedDownChecks: [] };
      const hoveredIncidentsData = null;

      // Act & Assert
      expect(() => render(<ChartBoxes monitor={monitor} hoveredIncidentsData={hoveredIncidentsData} />)).not.toThrow();
    });
  • Coverage improvements: Ensure that the tests cover all possible scenarios, including edge cases.
  • Performance testing needs: None identified.

6. Documentation & Maintenance

Documentation & Maintenance Considerations
  • Documentation updates needed: The documentation should be updated to reflect the changes in the incident display logic.
  • Long-term maintenance considerations: The change introduces a new layout for the "No incidents" scenario. It's important to ensure that this layout is maintained and updated as needed.
  • Technical debt and monitoring requirements: None identified.

7. Deployment & Operations

Deployment & Operations Considerations
  • Deployment impact and strategy: The change should be deployed as part of a regular release cycle.
  • Key operational considerations: None identified.

8. Summary & Recommendations

8.1 Key Action Items

  1. Critical changes required: Implement the suggested improvements to prevent errors and ensure consistency in the UI.
  2. Important improvements suggested: Use translations for the "No incidents" message to ensure consistency and ease of updates.
  3. Best practices to implement: None identified.
  4. Cross-cutting concerns to address: None identified.

8.2 Future Considerations

  • Technical evolution path: The change aligns with the technical evolution path of the application.
  • Business capability evolution: The change aligns with the business capability evolution of the application.
  • System integration impacts: The change does not introduce any new system integration impacts.

💡 Help Shape LlamaPReview
How's this review format working for you? Vote in our Github Discussion Polls to help us improve your review experience!

@gorkem-bwl
Copy link
Contributor

Can you please our one of standard fonts / colors from the theme? The font size / color of 'Incidents' header is a good fit for that.

@Br0wnHammer
Copy link
Contributor Author

1

Have made the changes.

@bluewave-labs bluewave-labs deleted a comment from coderabbitai bot Feb 14, 2025
Copy link
Collaborator

@ajhollid ajhollid left a comment

Choose a reason for hiding this comment

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

This PR is a bit too myopic in nature, it only works for this one component. What happens when another ChartBox needs an empty view? We have to search through the codebase to find this specific implementation and copy it in order to be consistent. This is not maintainable.

A more comprehensive and maintainable approach would be to implement an empty view for the ChartBox component. We would then have the same empty view for all components that use ChartBox.

Another note I am trying to remove all ternary and most inline conditional rendering from this project, so please avoid unless absolutely necessary, use early returns instead, it keeps the code much cleaner and readable.

@Br0wnHammer
Copy link
Contributor Author

This PR is a bit too myopic in nature, it only works for this one component. What happens when another ChartBox needs an empty view? We have to search through the codebase to find this specific implementation and copy it in order to be consistent. This is not maintainable.

A more comprehensive and maintainable approach would be to implement an empty view for the ChartBox component. We would then have the same empty view for all components that use ChartBox.

Another note I am trying to remove all ternary and most inline conditional rendering from this project, so please avoid unless absolutely necessary, use early returns instead, it keeps the code much cleaner and readable.

Alright, I understood your vision. We can create an empty view that takes in some kind of text as what to appear when we have an empty chartbox. Am I going in the right direction?

Additionally, for the ternary operation, yes I can remove the use of it altogether, I was not aware that you are thinking of removing them and hence thought that this can be used

@ajhollid
Copy link
Collaborator

ajhollid commented Feb 14, 2025

Alright, I understood your vision. We can create an empty view that takes in some kind of text as what to appear when we have an empty chartbox. Am I going in the right direction?

Yes, I think the approach you outlined is reasonable.

ChartBox can take a String to display as an empty view, with a default value of "No data" or something like that.

Additionally, for the ternary operation, yes I can remove the use of it altogether, I was not aware that you are thinking of removing them and hence thought that this can be used

Yes, I am trying to remove as much complexity as I can from the application. Please follow the principle of early return as much as possible rather than conditionally rendering things. In pseudo code:

if (!hasData) {
   return <EmptyView/>
}

return <RegularView/>>

instead of

return  hasData ? <RegularView/> : <EmptyView>  

If RegularView or EmptyView are long and complex component then a ternary becomes almost undreadable and very difficult to understand.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (4)
Client/src/Pages/Uptime/Details/Components/ChartBoxes/EmptyView.jsx (2)

5-13: Yo, let's make this component more theme-consistent and responsive!

The component looks solid, but we could improve it by:

  1. Using theme spacing for margins
  2. Using theme typography variants for consistent styling

Here's a more theme-consistent version:

-const EmptyView = ({ message = "No Data", size = "h2" }) => {
+const EmptyView = ({ message = "No Data", size = "h2", spacing = 8 }) => {
     return (
-        <Box m="auto" marginY="25%">
+        <Box 
+            m="auto" 
+            marginY={(theme) => theme.spacing(spacing)}
+            textAlign="center"
+        >
             <Typography variant={size}>
                 {message}
             </Typography>
         </Box>
     );
 };

15-20: Yo, let's beef up these PropTypes!

The PropTypes are good but could be more robust:

  1. Make message required since it's a core prop
  2. Add PropTypes for the spacing prop
 EmptyView.propTypes = {
-    message: PropTypes.string,
+    message: PropTypes.string.isRequired,
     size: PropTypes.oneOf(['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'body1', 'body2']),
+    spacing: PropTypes.number
 };
Client/src/Pages/Uptime/Details/Components/ChartBoxes/index.jsx (2)

40-81: Yo, this function's got a lot on its plate!

The renderUptime function could use some cleanup:

  1. Extract the hover timestamp display into a separate component
  2. Use theme typography variants instead of hard-coded font sizes
-                            fontSize={11}
+                            variant="caption"

Also, consider extracting the timestamp display:

const TimeStamp = ({ time, dateFormat, uiTimezone }) => (
    <Typography
        component="h5"
        position="absolute"
        top="100%"
        variant="caption"
        color={(theme) => theme.palette.primary.contrastTextTertiary}
    >
        {formatDateWithTz(time, dateFormat, uiTimezone)}
    </Typography>
);

165-175: Yo, let's make these PropTypes more specific!

The PropTypes could be more detailed, especially for complex objects:

-    monitor: PropTypes.object,
+    monitor: PropTypes.shape({
+        upChecks: PropTypes.shape({
+            totalChecks: PropTypes.number
+        }),
+        downChecks: PropTypes.shape({
+            totalChecks: PropTypes.number
+        }),
+        avgResponseTime: PropTypes.number,
+        groupedUpChecks: PropTypes.arrayOf(PropTypes.shape({
+            totalChecks: PropTypes.number,
+            _id: PropTypes.string
+        })),
+        groupedDownChecks: PropTypes.arrayOf(PropTypes.shape({
+            totalChecks: PropTypes.number,
+            _id: PropTypes.string
+        }))
+    }),
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 32d07fe and 002d0cc.

📒 Files selected for processing (2)
  • Client/src/Pages/Uptime/Details/Components/ChartBoxes/EmptyView.jsx (1 hunks)
  • Client/src/Pages/Uptime/Details/Components/ChartBoxes/index.jsx (5 hunks)
🔇 Additional comments (2)
Client/src/Pages/Uptime/Details/Components/ChartBoxes/EmptyView.jsx (1)

1-4: Yo, these imports are clean and organized!

The separation between component imports and utility imports is on point.

Client/src/Pages/Uptime/Details/Components/ChartBoxes/index.jsx (1)

110-115: Yo, this function's clean and lean!

The renderResponseTime function is well-structured with a good early return pattern.

Comment on lines 83 to 108
const renderIncidents = () => {
const downChecks = monitor?.groupedDownChecks?.reduce((count, checkGroup) => count + checkGroup.totalChecks, 0);
if (!downChecks && !hoveredIncidentsData) {
return <EmptyView message="Great. No incidents, yet!" />;
}
return (
<Box position="relative">
<Typography component="span">
{hoveredIncidentsData !== null
? hoveredIncidentsData.totalChecks
: downChecks}
</Typography>
{hoveredIncidentsData !== null && hoveredIncidentsData.time !== null && (
<Typography
component="h5"
position="absolute"
top="100%"
fontSize={11}
color={theme.palette.primary.contrastTextTertiary}
>
{formatDateWithTz(hoveredIncidentsData._id, dateFormat, uiTimezone)}
</Typography>
)}
</Box>
);
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Yo, we're seeing some code déjà vu here!

The renderIncidents function duplicates logic from renderUptime:

  1. TimeStamp display logic is repeated
  2. Hard-coded font size appears again

Extract shared components and use theme values:

-                        fontSize={11}
+                        variant="caption"

Consider creating a shared utility for check counting:

const getTotalChecks = (checks) => 
    checks?.reduce((count, checkGroup) => 
        count + checkGroup.totalChecks, 0) ?? 0;

@Br0wnHammer
Copy link
Contributor Author

@ajhollid @gorkem-bwl

WhatsApp.Video.2025-02-15.at.16.51.00.mp4

I have refactored Chartboxes and made early return statements.
I have made a new EmptyView component which can be reused as well.

@Br0wnHammer Br0wnHammer force-pushed the fix/fe/incidents-text branch from 002d0cc to a6bb756 Compare February 18, 2025 05:51
@Br0wnHammer Br0wnHammer force-pushed the fix/fe/incidents-text branch from a6bb756 to 2879126 Compare February 19, 2025 17:03
@Br0wnHammer
Copy link
Contributor Author

Hey @ajhollid , I have made use of low level empty view component.
Have also implemented early returns in case of noData is present.
For handling the logic and edge cases in when to have a empty view:
For Uptime:
I am using monitor?.uptimePercentage and monitor?.upChecks to efficiently determine if uptime data exists, avoiding unnecessary frontend calculations and ensuring a lightweight check for empty state handling.

Similarly for incidents:
I am using !monitor?.groupedDownChecks? to handle if there are incidents present for a particular monitor.

Screenshot 2025-02-19 at 10 54 05 AM Screenshot 2025-02-19 at 10 54 19 AM

Copy link

@coderabbitai coderabbitai bot left a comment

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)
src/Components/Charts/ChartBox/index.jsx (1)

7-18: 🛠️ Refactor suggestion

Yo dawg, let's complete those PropTypes!

I noticed some props being used but not validated. Let's fix that to keep our code tight!

Add these missing PropTypes:

 ChartBox.propTypes = {
   children: PropTypes.node,
   icon: PropTypes.node,
   header: PropTypes.string,
   height: PropTypes.string,
   noDataMessage: PropTypes.string,
-  isEmpty: PropTypes.bool
+  isEmpty: PropTypes.bool,
+  justifyContent: PropTypes.string,
+  Legend: PropTypes.node,
+  borderRadiusRight: PropTypes.number,
+  sx: PropTypes.object
 };
🧰 Tools
🪛 ESLint

[error] 12-12: 'justifyContent' is missing in props validation

(react/prop-types)


[error] 13-13: 'Legend' is missing in props validation

(react/prop-types)


[error] 14-14: 'borderRadiusRight' is missing in props validation

(react/prop-types)


[error] 15-15: 'sx' is missing in props validation

(react/prop-types)


[error] 15-15: 'sx' is defined but never used.

(no-unused-vars)

🧹 Nitpick comments (1)
src/Components/Charts/ChartBox/EmptyView.jsx (1)

7-15: Lose yourself in the optimization! 🎤

Consider memoizing this component to prevent unnecessary re-renders when parent updates.

+import { memo } from 'react';

 const EmptyView = ({
     icon,
     header,
     message = "No Data",
     size = "h2",
     borderRadiusRight = 4,
     justifyContent = "flex-start",
     height = "300px"
-}) => {
+}) => memo(() => {
     const theme = useTheme();
     // ... rest of the component
-};
+});
🧰 Tools
🪛 ESLint

[error] 12-12: 'borderRadiusRight' is missing in props validation

(react/prop-types)


[error] 13-13: 'justifyContent' is missing in props validation

(react/prop-types)


[error] 14-14: 'height' is missing in props validation

(react/prop-types)

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 002d0cc and 2879126.

📒 Files selected for processing (2)
  • src/Components/Charts/ChartBox/EmptyView.jsx (1 hunks)
  • src/Components/Charts/ChartBox/index.jsx (3 hunks)
🧰 Additional context used
🪛 ESLint
src/Components/Charts/ChartBox/EmptyView.jsx

[error] 12-12: 'borderRadiusRight' is missing in props validation

(react/prop-types)


[error] 13-13: 'justifyContent' is missing in props validation

(react/prop-types)


[error] 14-14: 'height' is missing in props validation

(react/prop-types)

🔇 Additional comments (2)
src/Components/Charts/ChartBox/index.jsx (1)

20-22: Straight fire! Early return pattern looking clean! 🔥

The early return pattern for empty state is well implemented. It improves code readability and reduces nesting.

src/Components/Charts/ChartBox/EmptyView.jsx (1)

66-68: Typography component looking clean! 💯

Good use of dynamic size prop with Typography component. The flexibility will help maintain consistent styling across different use cases.

Comment on lines 75 to 80
EmptyView.propTypes = {
message: PropTypes.string,
icon: PropTypes.node,
header: PropTypes.string,
size: PropTypes.oneOf(['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'body1', 'body2'])
};
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Mom's spaghetti time! Let's fix those PropTypes! 🍝

Static analysis caught some missing PropTypes. Let's add them to keep our code robust!

 EmptyView.propTypes = {
     message: PropTypes.string,
     icon: PropTypes.node,
     header: PropTypes.string,
-    size: PropTypes.oneOf(['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'body1', 'body2'])
+    size: PropTypes.oneOf(['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'body1', 'body2']),
+    borderRadiusRight: PropTypes.number,
+    justifyContent: PropTypes.string,
+    height: PropTypes.string
 };
📝 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
EmptyView.propTypes = {
message: PropTypes.string,
icon: PropTypes.node,
header: PropTypes.string,
size: PropTypes.oneOf(['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'body1', 'body2'])
};
EmptyView.propTypes = {
message: PropTypes.string,
icon: PropTypes.node,
header: PropTypes.string,
size: PropTypes.oneOf(['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'body1', 'body2']),
borderRadiusRight: PropTypes.number,
justifyContent: PropTypes.string,
height: PropTypes.string
};

Copy link
Collaborator

@ajhollid ajhollid left a comment

Choose a reason for hiding this comment

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

A good start, some refactoring is needed!

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
src/Components/Charts/ChartBox/EmptyView.jsx (1)

11-13: ⚠️ Potential issue

Fix missing PropTypes validation for justifyContent and height

There's vomit on your PropTypes already! Both justifyContent and height are missing in your props validation section.

Add these to the PropTypes definition:

 EmptyView.propTypes = {
     message: PropTypes.string,
     icon: PropTypes.node,
     header: PropTypes.string,
-    headingLevel: PropTypes.oneOf(['h1', 'h2', 'h3'])
+    headingLevel: PropTypes.oneOf(['h1', 'h2', 'h3']),
+    justifyContent: PropTypes.string,
+    height: PropTypes.string
 };
🧰 Tools
🪛 ESLint

[error] 12-12: 'justifyContent' is missing in props validation

(react/prop-types)


[error] 13-13: 'height' is missing in props validation

(react/prop-types)

🧹 Nitpick comments (1)
src/Components/Charts/ChartBox/EmptyView.jsx (1)

64-66: Review component prop usage in Typography

Mom's spaghetti moment! The Typography component is using the headingLevel prop directly in the component prop. This works but might cause unintended styling effects if headingLevel contains values other than valid HTML elements.

Consider validating against specific values or using a mapping function:

-    <Typography component={headingLevel}>
+    <Typography component={headingLevel} variant={headingLevel}>
         {message}
     </Typography>

This ensures both the DOM element AND the typography styling are consistent.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2879126 and f4021e8.

📒 Files selected for processing (2)
  • src/Components/Charts/ChartBox/EmptyView.jsx (1 hunks)
  • src/Pages/Uptime/Details/Components/ChartBoxes/index.jsx (2 hunks)
🧰 Additional context used
🪛 ESLint
src/Components/Charts/ChartBox/EmptyView.jsx

[error] 12-12: 'justifyContent' is missing in props validation

(react/prop-types)


[error] 13-13: 'height' is missing in props validation

(react/prop-types)

🔇 Additional comments (5)
src/Pages/Uptime/Details/Components/ChartBoxes/index.jsx (2)

48-48: Ensure strict comparison with uptimePercentage check

Your code checks if uptimePercentage is 0 using ===, which is good! But remember the time I had to do strict comparison checks in my code while my knees were weak and arms were heavy? It's important to stay consistent with strict comparisons throughout the codebase.


99-100:

❓ Verification inconclusive

Empty state logic implemented correctly - nice work!

This implementation of the EmptyView looks clean! The noDataMessage is clear and the isEmpty logic is appropriate. Mom's spaghetti would be proud of this code structure.

However, the "Average Response Time" ChartBox (lines 130-135) doesn't have empty state handling. Should we also check if avgResponseTime is 0?

Run the following script to check how often avgResponseTime might be 0:


🏁 Script executed:

#!/bin/bash
# Check for any instances where avgResponseTime might be handled specially when 0
rg "avgResponseTime.*(?:===|==|!==|!=).*0" --type js

Length of output: 54


Avg Response Time ChartBox: Consider Adding Empty State Handling

  • The empty state logic for the incidents ChartBox is spot on—Mom’s spaghetti would be proud!
  • However, for the "Average Response Time" ChartBox (lines 130-135), our initial search didn’t reveal any explicit check for when avgResponseTime equals 0.
  • Could you please verify if an empty state (e.g. isEmpty={avgResponseTime === 0}) is needed here to prevent displaying a misleading 0 value?
  • If so, kindly implement the necessary empty state handling; if not, add a quick comment clarifying the intended behaviour.
src/Components/Charts/ChartBox/EmptyView.jsx (3)

25-28: Consistent borderRadius usage

I see you're using borderRadius: 2 with different values for top/bottom right. I understand from past comments that you're matching the existing ChartBox component style, so this is appropriate.

Just to make sure we're being consistent, I'm verifying this matches other instances:

#!/bin/bash
# Check for borderRadius usage in ChartBox components
rg "borderRadius" --type js --context 2 src/Components/Charts/ChartBox/

39-47: Typography style overrides match ChartBox patterns

These typography style overrides help maintain visual consistency with the ChartBox component. Based on your previous explanation in comments, this makes sense to ensure consistent UI flow.


51-51: alignSelf usage is justified for layout requirements

I understand from your previous comment explanation why alignSelf is needed here - to align the header and icon to the start while keeping other content centered.

@vishnusn77 vishnusn77 self-requested a review February 25, 2025 18:52
Copy link
Collaborator

@ajhollid ajhollid left a comment

Choose a reason for hiding this comment

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

Alright, looks

Copy link
Contributor

Choose a reason for hiding this comment

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

looks good to me

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
src/Components/Charts/ChartBox/EmptyView.jsx (3)

24-24: Knees weak, typo in the JSDoc example

There's a typo in the JSDoc example: "Resposne" should be "Response".

-   message="No Resposne Time Available"
+   message="No Response Time Available"

66-69: Arms are heavy! Overridden typography styles

I see you're overriding h2 styles to match the ChartBox component. As discussed in previous comments, this creates inconsistency with the theme, but is necessary for now to match the existing ChartBox implementation.

Consider adding a TODO comment noting that both components should eventually be refactored to use theme typography styles consistently.

                    "& h2": {
+                       // TODO: Eventually refactor both EmptyView and ChartBox to use theme typography consistently
                        color: theme.palette.primary.contrastTextSecondary,
                        fontSize: 15,
                        fontWeight: 500,
                    },

90-92: He's nervous! Component vs variant for Typography

You're using the component prop to set the heading level, but not specifying a variant. For Material-UI's Typography, component controls the rendered HTML element while variant controls the styling.

-                    <Typography component={headingLevel}>
+                    <Typography component={headingLevel} variant={headingLevel}>
                         {message}
                     </Typography>
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f4021e8 and 3650a61.

📒 Files selected for processing (2)
  • src/Components/Charts/ChartBox/EmptyView.jsx (1 hunks)
  • src/Pages/Uptime/Details/Components/ChartBoxes/index.jsx (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/Pages/Uptime/Details/Components/ChartBoxes/index.jsx
🔇 Additional comments (2)
src/Components/Charts/ChartBox/EmptyView.jsx (2)

1-108: Mom's spaghetti! Nice new EmptyView component implementation

The component is well-structured with comprehensive JSDoc documentation and proper prop types. The implementation handles empty states elegantly with customizable icon, header, and message.


52-55: Vomit on his sweater already! Mixed border radius values

I notice you're using both borderRadius: 2 and specific borderTopRightRadius/borderBottomRightRadius: 4. From the previous comments, I see this was intentional to match ChartBox styling.

Consider adding a borderRadiusRight prop for consistency with ChartBox component to make this configurable, since there was previous discussion about this.

-                borderRadius: 2,
-                borderTopRightRadius: 4,
-                borderBottomRightRadius: 4,
+                borderRadius: 2,
+                borderTopRightRadius: borderRadiusRight || 4,
+                borderBottomRightRadius: borderRadiusRight || 4,

And update props and PropTypes:

 const EmptyView = ({
     icon,
     header,
     message = "No Data",
     headingLevel = "h2",
     justifyContent = "flex-start",
+    borderRadiusRight,
     height = "100%"
 }) => {
 EmptyView.propTypes = {
     message: PropTypes.string,
     icon: PropTypes.node,
     header: PropTypes.string,
     headingLevel: PropTypes.oneOf(['h1', 'h2', 'h3']),
     justifyContent: PropTypes.string,
+    borderRadiusRight: PropTypes.number,
     height: PropTypes.string
 };

Copy link
Contributor

@vishnusn77 vishnusn77 left a comment

Choose a reason for hiding this comment

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

Looks good to merge @ajhollid

@Br0wnHammer
Copy link
Contributor Author

Hey @vishnusn77, can you approve the PR if everything seems fine. Alex is a bit busy with some work and asked for any of the maintainers to review and approve it.

@ajhollid ajhollid dismissed their stale review February 27, 2025 18:58

Time restrictions

@ajhollid ajhollid merged commit 461006c into bluewave-labs:develop Feb 27, 2025
1 check passed
@Br0wnHammer Br0wnHammer deleted the fix/fe/incidents-text branch February 27, 2025 19:02
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.

4 participants