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

Center align Loading component based on remaining screen height #8976

Merged

Conversation

Suhail2701
Copy link
Contributor

@Suhail2701 Suhail2701 commented Nov 1, 2024

Fixes #8762 - Repositions the page loader to be centered on the all pages.

This PR updates the loader component’s CSS, ensuring that it appears in the center of the screen on all pages.

After Changes:
Loader

Summary by CodeRabbit

  • New Features

    • Enhanced the Loading component for improved responsiveness and adaptability based on viewport position.
  • Bug Fixes

    • Resolved layout issues by transitioning from a grid system to a flexbox model for better alignment and centering.
  • Refactor

    • Simplified the inner structure of the Loading component while maintaining a fixed width for the logo.

@Suhail2701 Suhail2701 requested a review from a team as a code owner November 1, 2024 06:30
Copy link

netlify bot commented Nov 1, 2024

Deploy Preview for care-ohc ready!

Name Link
🔨 Latest commit 8e0a2e5
🔍 Latest deploy log https://app.netlify.com/sites/care-ohc/deploys/673369d0c2f36a0008433a65
😎 Deploy Preview https://deploy-preview-8976--care-ohc.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

src/components/Common/Loading.tsx Outdated Show resolved Hide resolved
src/components/Common/Loading.tsx Outdated Show resolved Hide resolved
package-lock.json Outdated Show resolved Hide resolved
@rithviknishad
Copy link
Member

@Suhail2701 keep readable titles for the PR and fo follow the PR template which includes the merge checklist.

@rithviknishad rithviknishad added invalid This doesn't seem right changes required labels Nov 2, 2024
@Suhail2701
Copy link
Contributor Author

Hi @rithviknishad,

I have updated the Loading component as you mentioned. Kindly check it and let me know your feedback.

Thank you!

@bodhish
Copy link
Member

bodhish commented Nov 5, 2024

@coderabbitai full review

Copy link
Contributor

coderabbitai bot commented Nov 5, 2024

✅ Actions performed

Full review triggered.

Copy link
Contributor

coderabbitai bot commented Nov 5, 2024

Caution

Review failed

The pull request is closed.

Walkthrough

The changes in the Loading component involve the introduction of a new state variable offsetTop and a reference containerRef to dynamically manage the component's height based on its viewport position. The useEffect hook calculates offsetTop using getBoundingClientRect(), which updates on component mount and during window resize and scroll events. The layout has transitioned from a grid to a flexbox model, enhancing responsiveness, while the outer div now adjusts its height dynamically. The inner structure has been simplified with a fixed width for the logo.

Changes

File Path Change Summary
src/components/Common/Loading.tsx Introduced offsetTop state and containerRef; implemented useEffect for dynamic height adjustment; changed layout to flexbox; simplified inner structure.

Assessment against linked issues

Objective Addressed Explanation
Reposition the page loader in main homepages to be placed in the center (8762)

🐇 In the meadow, the loader spins,
Centered now, where joy begins.
With flex and height, it finds its place,
A dance of pixels, a happy space!
Hopping high, the changes gleam,
A loading dream, a coder's dream! 🌼

Warning

There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure.

🔧 eslint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

src/components/Common/Loading.tsx

Oops! Something went wrong! :(

ESLint: 8.57.1

Error: Failed to load parser '@typescript-eslint/parser' declared in '.eslintrc.json': Cannot find module '@typescript-eslint/parser'
Require stack:

  • /.eslintrc.json
    at Module._resolveFilename (node:internal/modules/cjs/loader:1248:15)
    at Function.resolve (node:internal/modules/helpers:145:19)
    at Object.resolve (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2346:46)
    at ConfigArrayFactory._loadParser (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3325:39)
    at ConfigArrayFactory._normalizeObjectConfigDataBody (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3099:43)
    at _normalizeObjectConfigDataBody.next ()
    at ConfigArrayFactory._normalizeObjectConfigData (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3040:20)
    at _normalizeObjectConfigData.next ()
    at ConfigArrayFactory.loadInDirectory (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2886:28)
    at CascadingConfigArrayFactory._loadConfigInAncestors (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3871:46)

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:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • 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 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 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 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 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
Contributor

@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 and nitpick comments (8)
src/components/Common/Loading.tsx (1)

8-8: Consider using responsive width classes.

The fixed w-2/12 width might not provide the best experience across all screen sizes. Consider using responsive width classes or max-width constraints.

-      <div className="w-2/12">
+      <div className="w-2/12 sm:w-3/12 md:w-2/12 max-w-xs">
src/components/Facility/FacilityList.tsx (1)

113-113: Consider making the loader height responsive.

While setting minHeightClass="min-h-[600px]" helps center the loader, consider making it responsive for better mobile experience:

-    manageFacilities = <Loading minHeightClass={"min-h-[600px]"} />;
+    manageFacilities = <Loading minHeightClass={"min-h-[300px] md:min-h-[450px] lg:min-h-[600px]"} />;
src/components/Patient/SampleViewAdmin.tsx (1)

287-289: Consider using viewport-based height for better responsiveness.

While the fixed min-h-[600px] works well for standard viewports, consider using a viewport-based height for better responsiveness across different screen sizes.

-        <Loading minHeightClass={"min-h-[600px]"} />
+        <Loading minHeightClass={"min-h-[60vh]"} />
src/components/Assets/AssetsList.tsx (2)

212-212: Consider standardizing the minimum height value across components.

The minHeightClass value of "min-h-[500px]" differs from the "min-h-[600px]" used in other components (FacilityList, ManagePatients, etc.). Consider standardizing this value for consistent loading state appearance across the application.

-        <Loading minHeightClass={"min-h-[500px]"} />
+        <Loading minHeightClass={"min-h-[600px]"} />

Line range hint 156-189: Consolidate loading state management.

The loading state is being reset in multiple places (try block, catch block, and finally block). This could lead to race conditions or state inconsistencies. Consider letting the finally block handle all loading state resets.

 const accessAssetIdFromQR = async (assetURL: string) => {
   try {
     setIsLoading(true);
     setIsScannerActive(false);
     if (!isValidURL(assetURL)) {
-      setIsLoading(false);
       Notification.Error({
         msg: t("invalid_asset_id_msg"),
       });
       return;
     }
     const params = parseQueryParams(assetURL);
     // QR Maybe searchParams "asset" or "assetQR"
     // If no params found, then use assetText
     const assetId = params.asset || params.assetQR;

     if (assetId) {
       const { data } = await request(routes.listAssetQR, {
         pathParams: { qr_code_id: assetId },
       });
       if (!data) {
-        setIsLoading(false);
         Notification.Error({
           msg: t("invalid_asset_id_msg"),
         });
         return;
       }
       const { data: assetData } = await request(routes.listAssets, {
         query: { qr_code_id: assetId, limit: 1 },
       });
       if (assetData?.results.length === 1) {
         navigate(
           `/facility/${assetData.results[0].location_object.facility?.id}/assets/${assetData.results[0].id}`,
         );
       } else {
-        setIsLoading(false);
         Notification.Error({
           msg: t("asset_not_found_msg"),
         });
       }
     } else {
-      setIsLoading(false);
       Notification.Error({
         msg: t("invalid_asset_id_msg"),
       });
     }
   } catch (err) {
     Notification.Error({
       msg: t("invalid_asset_id_msg"),
     });
   } finally {
     setIsLoading(false);
   }
 };
src/components/Users/ManageUsers.tsx (2)

469-469: Consider making the min-height value more flexible.

While the minHeightClass prop helps position the loader, the hardcoded value of "min-h-[600px]" might not be optimal for all viewport sizes.

Consider one of these approaches:

  1. Make it responsive using viewport units:
-manageUsers = <Loading minHeightClass={"min-h-[600px]"} />;
+manageUsers = <Loading minHeightClass={"min-h-[60vh]"} />;
  1. Pass it as a prop from the parent to allow for context-specific heights:
-manageUsers = <Loading minHeightClass={"min-h-[600px]"} />;
+manageUsers = <Loading minHeightClass={loadingMinHeightClass} />;

Line range hint 1-1000: Consider breaking down the component for better maintainability.

The ManageUsers component handles multiple responsibilities including user listing, filtering, facility management, and working hours management. This could make it harder to maintain and test.

Consider these architectural improvements:

  1. Extract facility management logic into a separate service/hook:
// hooks/useFacilityManagement.ts
export function useFacilityManagement(username: string) {
  const updateHomeFacility = async (facility: any) => {
    // ... facility update logic
  };
  
  const unlinkFacility = async (facility: any) => {
    // ... facility unlink logic
  };
  
  return { updateHomeFacility, unlinkFacility };
}
  1. Create a custom hook for user filtering logic:
// hooks/useUserFilters.ts
export function useUserFilters() {
  // ... filtering logic
  return { filters, updateFilters };
}
  1. Split the UserFacilities component into its own file since it's a significant piece of functionality.

These changes would improve code organization, reusability, and testability.

src/components/Patient/ManagePatients.tsx (1)

757-757: Consider using responsive units for minHeightClass

The hardcoded min-h-[500px] may not display optimally on all screen sizes, especially smaller devices. To enhance responsiveness, consider using Tailwind CSS responsive classes to adjust the minimum height based on screen size.

Apply this diff to make the minHeightClass responsive:

-<Loading minHeightClass={"min-h-[500px]"} />
+<Loading minHeightClass={"min-h-screen md:min-h-[500px]"} />
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 764cfe3 and 0b057bb.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (6)
  • src/components/Assets/AssetsList.tsx (1 hunks)
  • src/components/Common/Loading.tsx (1 hunks)
  • src/components/Facility/FacilityList.tsx (1 hunks)
  • src/components/Patient/ManagePatients.tsx (1 hunks)
  • src/components/Patient/SampleViewAdmin.tsx (1 hunks)
  • src/components/Users/ManageUsers.tsx (1 hunks)
🔇 Additional comments (3)
src/components/Common/Loading.tsx (2)

9-9: Consider replacing App-logo CSS class with Tailwind.

In line with the previous review comment about mixing CSS and Tailwind, consider replacing the App-logo CSS class with equivalent Tailwind classes if it's only handling simple styling.

Let's check the App-logo CSS definition:

#!/bin/bash
# Description: Find App-logo CSS definition
# Expected: CSS properties that could be replaced with Tailwind

# Search for App-logo class definition
rg 'App-logo' --type css

3-7: LGTM! The loader positioning implementation looks good.

The changes effectively address the centering requirements by:

  • Using flex layout with proper centering classes
  • Making the height configurable via props

Let's verify the loader usage across different pages:

✅ Verification successful

The Loading component implementation and usage patterns are verified as appropriate

The verification shows:

  • The component is used consistently across multiple pages with proper minHeightClass customization:
    • Default min-h-screen works for full-page loads
    • Custom heights like min-h-[500px] and min-h-[600px] are used appropriately in list views
  • The App-logo CSS is properly defined with:
    • Responsive height (10vmin)
    • Proper animation for the loading state
    • Consistent styling across the app
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check Loading component usage patterns
# Expected: Various minHeightClass values across different pages

# Search for Loading component usage
rg -A 2 '<Loading' --type tsx

Length of output: 308


Script:

#!/bin/bash
# Let's try different search patterns to find Loading component usage

# Search for Loading import statements
rg -l "import.*Loading.*from.*Common" --type tsx

# Search for Loading component with word boundaries
rg -A 2 "\bLoading\b.*>" --type tsx

# Search for files containing Loading component
fd -e tsx -x grep -l "Loading"

# Check the actual component implementation
cat src/components/Common/Loading.tsx

Length of output: 6020


Script:

#!/bin/bash
# Let's check the actual usage patterns of the Loading component

# Check a few key files that might show different usage patterns
echo "=== AssetsList.tsx ==="
rg -A 3 -B 1 '<Loading' src/components/Assets/AssetsList.tsx || true

echo "=== UserProfile.tsx ==="
rg -A 3 -B 1 '<Loading' src/components/Users/UserProfile.tsx || true

echo "=== ResourceList.tsx ==="
rg -A 3 -B 1 '<Loading' src/components/Resource/ResourceList.tsx || true

# Check for any custom minHeightClass props
echo "=== Custom minHeightClass usage ==="
rg '<Loading.*minHeightClass' . || true

# Check the CSS file for App-logo styles
echo "=== App-logo CSS ==="
cat src/style/index.css || true

Length of output: 25868

src/components/Patient/SampleViewAdmin.tsx (1)

287-289: LGTM! Effective centering solution implemented.

The combination of flex container with justify-center and the explicit min-h-[600px] ensures proper vertical centering of the loader, addressing the positioning issue described in #8762.

@@ -110,7 +110,7 @@ export const FacilityList = () => {
}

if (isLoading || !permittedData) {
manageFacilities = <Loading />;
manageFacilities = <Loading minHeightClass={"min-h-[600px]"} />;
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Based on the search results, I can generate the final response as I have sufficient information about the Loading component usage across the codebase:

Height inconsistency detected in Loading component usage

The Loading component is used with different height configurations across the codebase:

  • min-h-[600px] in FacilityList.tsx and ManageUsers.tsx
  • min-h-[500px] in ManagePatients.tsx and AssetsList.tsx
  • Most other occurrences have no height specification

Consider standardizing the loading height:

  • Either remove the custom height from FacilityList.tsx to match majority usage
  • Or establish a consistent height standard across all list views (ManageUsers, ManagePatients, AssetsList)
🔗 Analysis chain

Verify consistent loader height across components.

Let's ensure this height value is consistently applied across other components using the Loading component.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other Loading component usages to verify consistent height values
rg -A 1 '<Loading' | grep -v 'FacilityList.tsx'

Length of output: 10138

@github-actions github-actions bot added the merge conflict pull requests with merge conflict label Nov 6, 2024
Copy link

github-actions bot commented Nov 6, 2024

👋 Hi, @Suhail2701,
Conflicts have been detected against the base branch. Please rebase your branch against the base branch.


This message is automatically generated by prince-chrismc/label-merge-conflicts-action so don't hesitate to report issues/improvements there.

@sainak sainak removed the merge conflict pull requests with merge conflict label Nov 6, 2024
src/components/Common/Loading.tsx Outdated Show resolved Hide resolved
src/components/Common/Loading.tsx Outdated Show resolved Hide resolved
@rithviknishad rithviknishad changed the title Issues/8762/reposition loader Center align Loading component based on remaining screen height Nov 12, 2024
Copy link
Contributor

@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

🧹 Outside diff range and nitpick comments (2)
src/components/Common/Loading.tsx (2)

7-24: Optimize event listeners for better performance

The current implementation could cause frequent recalculations. Consider these optimizations:

  1. Add debounce to the resize and scroll handlers
  2. Remove capture phase from scroll listener unless specifically needed

Consider this implementation:

+import { debounce } from 'lodash';
+
 useEffect(() => {
-  const calculateOffset = () => {
+  const calculateOffset = debounce(() => {
     if (containerRef.current) {
       const rect = containerRef.current.getBoundingClientRect();
       setOffsetTop(rect.top);
     }
-  };
+  }, 100);

   calculateOffset();

   window.addEventListener("resize", calculateOffset);
-  window.addEventListener("scroll", calculateOffset, true);
+  window.addEventListener("scroll", calculateOffset);

   return () => {
     window.removeEventListener("resize", calculateOffset);
-    window.removeEventListener("scroll", calculateOffset, true);
+    window.removeEventListener("scroll", calculateOffset);
+    calculateOffset.cancel();
   };
 }, []);

32-37: Make logo width responsive

Using a fixed width ratio (w-2/12) might not work well across all screen sizes. Consider using responsive classes or max-width constraints.

Apply this diff:

-<div className="w-2/12">
+<div className="w-32 sm:w-40 md:w-48 lg:w-56 max-w-[16.666667%]">
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 0b057bb and 5375544.

📒 Files selected for processing (1)
  • src/components/Common/Loading.tsx (1 hunks)
🔇 Additional comments (3)
src/components/Common/Loading.tsx (3)

1-6: 🛠️ Refactor suggestion

Add className prop for better component reusability

The component should accept a className prop to allow customization from parent components, as suggested in previous reviews.

Apply this diff:

-const Loading = () => {
+const Loading = (props: { className?: string }) => {
   const containerRef = useRef<HTMLDivElement>(null);
   const [offsetTop, setOffsetTop] = useState(0);

27-31: 🛠️ Refactor suggestion

Use className prop and avoid mixing styles

  1. The className prop should be used with the container div
  2. Avoid mixing inline styles with Tailwind when possible

Apply this diff:

 <div
   ref={containerRef}
-  className="flex w-full items-center justify-center transition-[height]"
-  style={{ height: `calc(100vh - ${offsetTop}px)` }}
+  className={cn(
+    "flex w-full items-center justify-center transition-[height]",
+    `h-[calc(100vh-${offsetTop}px)]`,
+    props.className
+  )}
 >

1-42: Verify loader positioning across different scenarios

While the implementation should center the loader correctly, please verify these scenarios:

  1. Different page layouts and tab switches
  2. Various screen sizes
  3. Dynamic content changes that might affect positioning

Run this script to find all usage locations:

✅ Verification successful

Based on the search results, I can see that the Loading component is used extensively throughout the application in various scenarios like data fetching, form submissions, and route transitions. The component is consistently used as a full-page loader with the height calculation logic to ensure proper centering.

Let me generate the final response:

Loading component implementation looks correct and well-used

The dynamic height calculation implementation in the Loading component is appropriate and works well with the application's needs:

  • Used consistently across 50+ components as a full-page loader
  • Handles various scenarios including Suspense fallbacks, data loading states, and form submissions
  • The height calculation ensures proper vertical centering regardless of the page layout or header height
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Find all files that import and use the Loading component
rg -l "import.*Loading.*from.*Common/Loading" | xargs rg "Loading"

Length of output: 31913

@nihal467
Copy link
Member

LGTM

@rithviknishad rithviknishad merged commit 4745e6d into ohcnetwork:develop Nov 12, 2024
3 of 5 checks passed
Copy link

@Suhail2701 Your efforts have helped advance digital healthcare and TeleICU systems. 🚀 Thank you for taking the time out to make CARE better. We hope you continue to innovate and contribute; your impact is immense! 🙌

UdaySagar-Git pushed a commit to UdaySagar-Git/care_fe that referenced this pull request Dec 3, 2024
@coderabbitai coderabbitai bot mentioned this pull request Dec 15, 2024
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

Reposition the page loader in main homepages to be placed in the center
7 participants