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

Enhanced Resource Page #9768

Closed

Conversation

manmeetnagii
Copy link
Contributor

@manmeetnagii manmeetnagii commented Jan 5, 2025

Proposed Changes

@ohcnetwork/care-fe-code-reviewers

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a new comprehensive Resource Management page with dynamic Kanban board and list views.
    • Added ability to filter and toggle between active and completed resources.
    • Implemented drag-and-drop functionality for resource status updates.
  • Localization

    • Added new translation key for resource category.
  • Refactor

    • Removed separate Board and List view components.
    • Consolidated resource management into a single, more flexible ResourcePage component.
  • Improvements

    • Enhanced resource management interface with export and search capabilities.
    • Added multi-language support for resource management features.

@manmeetnagii manmeetnagii requested a review from a team as a code owner January 5, 2025 17:58
Copy link
Contributor

coderabbitai bot commented Jan 5, 2025

Walkthrough

This pull request introduces changes to the resource management interface by adding a new ResourcePage component while removing the existing BoardView and ListView components. It updates the routing configuration to render the ResourcePage directly, eliminating previous redirection logic. Additionally, a new localization key is added to enhance the user interface for resource categorization.

Changes

File Change Summary
public/locale/en.json Added a new localization key: "resource_category"
src/Routers/routes/ResourceRoutes.tsx Removed Redirect and default view logic, directly rendering ResourcePage
src/components/Kanban/Board.tsx Completely removed KanbanBoard and KanbanSection components
src/components/Resource/ResourceBoard.tsx Deleted entire BoardView component
src/components/Resource/ResourceList.tsx Deleted entire ListView component
src/components/Resource/ResourcePage.tsx Added new ResourcePage component with integrated board and list view functionality

Assessment against linked issues

Objective Addressed Explanation
Consistent Board/List switch design [#9677]
Fix resource count and layout [#9901] Requires visual verification of count accuracy
Remove unnecessary scrollbars [#9971] Needs UI testing to confirm scrollbar resolution
Prevent displaying same medicine across all statuses [#9976] Requires detailed testing of resource status filtering

Possibly related PRs

Suggested labels

tested

Suggested reviewers

  • rithviknishad
  • Jacobjeevan

Poem

🐰 Hop, hop, through code's green meadow,
Resources dance, no longer in shadow!
Board and list, now united as one,
A rabbit's refactor, brilliantly done! 🌈
Drag, drop, and view with pure delight! 🎉


📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 78c9288 and 778f18f.

📒 Files selected for processing (1)
  • public/locale/en.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • public/locale/en.json
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: Test
  • GitHub Check: lint
  • GitHub Check: cypress-run (1)
  • GitHub Check: auto-label
  • GitHub Check: CodeQL-Build

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 generate docstrings to generate docstrings for this PR. (Beta)
  • @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

netlify bot commented Jan 5, 2025

Deploy Preview for care-ohc ready!

Name Link
🔨 Latest commit 778f18f
🔍 Latest deploy log https://app.netlify.com/sites/care-ohc/deploys/67905842fdca660008be7d83
😎 Deploy Preview https://deploy-preview-9768--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.

@manmeetnagii
Copy link
Contributor Author

@rithviknishad review this one

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

🧹 Nitpick comments (4)
src/components/Kanban/Board.tsx (1)

38-39: Removed horizontal scrolling buttons and simplified layout.

The new two-tier container approach (outer

+ flex boxes) is neat. Ensure no accessibility regression for users who relied on the previous scroll control.

src/components/Resource/ResourceCardList.tsx (1)

26-85: Card layout effectively conveys resource info.

Using a grid and separate display for title, status, and emergency badge is clear, providing a well-organized view. Ensure each field is accessible with descriptive ARIA labels if needed.

src/components/Resource/ResourcePage.tsx (1)

94-126: Consider removing redundant fragments.

A fragment wrapping a single child is flagged by the linter. You can safely remove it to reduce JSX verbosity.

- <>
   <div className="flex lg:flex-row flex-col w-full justify-end gap-2">
- </>
🧰 Tools
🪛 Biome (1.9.4)

[error] 94-126: Avoid using unnecessary Fragment.

A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment

(lint/complexity/noUselessFragments)

public/locale/en.json (1)

1616-1616: LGTM! Consider adding a placeholder variant.

The new translation key follows the naming convention and is properly placed. For consistency with other selection fields in the application, consider adding a placeholder variant:

 "select_status": "Select Status",
+"select_status_placeholder": "Select a status",
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between c34bf37 and 66126a4.

📒 Files selected for processing (7)
  • public/locale/en.json (1 hunks)
  • src/Routers/routes/ResourceRoutes.tsx (1 hunks)
  • src/components/Kanban/Board.tsx (3 hunks)
  • src/components/Resource/ResourceBoard.tsx (0 hunks)
  • src/components/Resource/ResourceCardList.tsx (1 hunks)
  • src/components/Resource/ResourceList.tsx (0 hunks)
  • src/components/Resource/ResourcePage.tsx (1 hunks)
💤 Files with no reviewable changes (2)
  • src/components/Resource/ResourceList.tsx
  • src/components/Resource/ResourceBoard.tsx
🧰 Additional context used
🪛 Biome (1.9.4)
src/components/Resource/ResourcePage.tsx

[error] 94-126: Avoid using unnecessary Fragment.

A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment

(lint/complexity/noUselessFragments)

🔇 Additional comments (16)
src/Routers/routes/ResourceRoutes.tsx (2)

3-3: Successfully imported the new ResourcePage component.

The import statement is clear and aligns with the consolidated view approach.


8-8: Route consolidation looks good.

Replacing the old BoardView/ListView routes with ResourcePage is consistent with the PR objective of unifying the resource views.

src/components/Kanban/Board.tsx (2)

137-137: Height change from calc(100vh-200px) to calc(100vh-340px).

Increasing the offset reduces visible space, which might cause more scrolling. Verify on smaller devices to ensure no usability issues.


169-169: Placeholder usage in Droppable context.

Including provided.placeholder ensures proper rendering of dragged items. This is currently a best practice for React DnD.

src/components/Resource/ResourceCardList.tsx (5)

1-3: Imports are well-structured.

Imports for Link and useTranslation are minimal and aligned with usage below.


11-13: Interface definition is clear.

ResourceCardListProps is concise, making the component’s expected data structure explicit.


18-24: Graceful handling of empty data.

Rendering "no_results_found" message improves user feedback when there are no resources.


131-135: “View all details” link for each resource.

This link offers a direct route to resource details, improving discoverability.


142-142: Export statement confirmed.

Exporting ResourceCardList as default matches the new consolidated design approach.

src/components/Resource/ResourcePage.tsx (7)

42-45: Lazy loading the KanbanBoard component.

This reduces initial bundle size and is a strong performance optimization for routes that may not require the board immediately.


51-67: ResourcePage initialization logic.

Storing filter states (boardFilter, viewMode) is straightforward. The fallback to default active statuses plus an option for completed items is well-structured.


68-77: Fetch logic using useTanStackQueryInstead.

Looks correct. The query configuration matches the advanced filter structure. Confirm that all relevant data fields are included in the final payload for the Resource list.


79-84: Export function for CSV.

Nice use of request with csv: true. This helps quickly integrate a CSV export feature.


129-227: Board view integration.

The board filter and drag-and-drop updates to resource status align well with the consolidated view. Watch out for edge cases when switching between active and completed boards.


228-297: List view integration with advanced filters.

Combining the ResourceCardList, refresh actions, and pagination is well-organized. The consistent approach to filtering across both views helps unify UX.


302-302: Exporting ResourcePage.

This final export aligns with the route changes in ResourceRoutes.tsx, ensuring navigational consistency.

@rithviknishad
Copy link
Member

rithviknishad commented Jan 5, 2025

  1. Solve conflicts in old PR itself instead of reopening new PRs. Use it as an opportunity to learn git.

  2. Changes requested in previous PR are not done here.

@manmeetnagii
Copy link
Contributor Author

  1. Solve conflicts in old PR itself instead of reopening new PRs. Use it as an opportunity to learn git.
  2. Changes requested in previous PR are not done here.

I am unable to reopen that PR as I've reforked the repo 😅

@rithviknishad
Copy link
Member

solve the changes requested in previous PR here atleast then?

@rithviknishad rithviknishad reopened this Jan 5, 2025
@manmeetnagii
Copy link
Contributor Author

solve the changes requested in previous PR here atleast then?

I think I've done that🤔Let me list the changes.

  1. Deletion of ''/resource/board'' and ''/resource/list' routes and components' files related to them. ✅
  2. Removal of ''log updates" ✅
  3. Created a separate component for ResourceCardList ✅
  4. Deletion of https://github.com/ohcnetwork/care_fe/blob/develop/src/components/Kanban/Board.tsx. file. This file is used in ResourcePage.tsx component that's why I didn't delete it.

@github-actions github-actions bot added needs-triage question Further information is requested labels Jan 5, 2025
@rithviknishad
Copy link
Member

let's keep the implementation idential to the one in appointments, and delete that kanban board

@manmeetnagii
Copy link
Contributor Author

let's keep the implementation idential to the one in appointments, and delete that kanban board

got it

@Jacobjeevan Jacobjeevan added changes required and removed question Further information is requested needs-triage labels Jan 5, 2025
@manmeetnagii
Copy link
Contributor Author

manmeetnagii commented Jan 6, 2025

let's keep the implementation idential to the one in appointments, and delete that kanban board

@rithviknishad Do we need DragDropContext in resource page board view?

@github-actions github-actions bot added needs-triage question Further information is requested labels Jan 6, 2025
@manmeetnagii
Copy link
Contributor Author

@rithviknishad , I’ve tried implementing this in the same way as the AppointmentPage. Is this correct?

const appliedFilters = formatFilter(qParams);
const [viewMode, setViewMode] = useState<"board" | "list">("board");
const { exportFile } = useExport();
const { loading, data, refetch } = useTanStackQueryInstead(
Copy link
Contributor

Choose a reason for hiding this comment

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

Switch to using useQuery + query here.

Do the same for other API calls in this component 👍

});
return data as QueryResponse<T>;
} catch (error) {
console.error("Error fetching section data:", error);
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove the console log

const options = section.fetchOptions(section.id);
const fetchPage = async ({ pageParam = 0 }) => {
try {
const data = await callApi(options.route, {
Copy link
Contributor

Choose a reason for hiding this comment

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

useQuery instead of callApi.

const [boardFilter, setBoardFilter] = useState(ACTIVE);
// eslint-disable-next-line
const appliedFilters = formatFilter(qParams);
const [viewMode, setViewMode] = useState<"board" | "list">("board");
Copy link
Contributor

Choose a reason for hiding this comment

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

You should add the logic for storing in localStorage for viewMode, right now it resets on every page load.

We can create a hook to handle that in a different issue, since we will have multiple components having a similar view.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Jacobjeevan for now I've use useEffect, should I create a new issue for the hook itself? 🤔

Copy link
Contributor

Choose a reason for hiding this comment

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

Nah, @Mahendar0701 is taking care of that in another issue.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nah, @Mahendar0701 is taking care of that in another issue.

@Jacobjeevan okay, should I remove my implementation then or keep it as it is?🤔

Copy link
Contributor

Choose a reason for hiding this comment

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

Keep as is.

@manmeetnagii
Copy link
Contributor Author

@rithviknishad @Jacobjeevan any update on this? 😅

SelectTrigger,
SelectValue,
} from "../ui/select";
import { Tabs, TabsList, TabsTrigger } from "../ui/tabs";
Copy link
Contributor

Choose a reason for hiding this comment

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

minor thing, but absolute imports

const [boardFilter, setBoardFilter] = useState(ACTIVE);
// eslint-disable-next-line
const appliedFilters = formatFilter(qParams);
const [viewMode, setViewMode] = useState<"board" | "list">("board");
Copy link
Contributor

Choose a reason for hiding this comment

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

Nah, @Mahendar0701 is taking care of that in another issue.

src/components/Resource/ResourcePage.tsx Outdated Show resolved Hide resolved
Comment on lines 148 to 163
<Select
defaultValue="active"
onValueChange={(value) =>
setBoardFilter(value === "completed" ? COMPLETED : ACTIVE)
}
>
<SelectTrigger className="w-full lg:w-[180px]">
<SelectValue defaultValue={"completed"} />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectItem value="active">{t("active")}</SelectItem>
<SelectItem value="completed">{t("completed")}</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
Copy link
Contributor

Choose a reason for hiding this comment

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

@manmeetnagii ☝️ Also you don't need to specify defaultValue in both places.

@Jacobjeevan Jacobjeevan removed question Further information is requested Deploy-Failed Deplyment is not showing preview needs-triage labels Jan 17, 2025
Copy link
Contributor

@Jacobjeevan Jacobjeevan left a comment

Choose a reason for hiding this comment

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

Check the previous review as well, missed one.

variant="secondary"
className=" bg-transparent shadow-none text-black rounded-full"
action={async () => {
const { data } = await request(
Copy link
Contributor

Choose a reason for hiding this comment

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

There's still this request :)

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: 2

🧹 Nitpick comments (3)
src/components/Resource/ResourcePage.tsx (3)

1-18: Convert relative imports to absolute imports.

Based on the previous review comments, the codebase follows a convention of using absolute imports.

-import { useTranslation } from "react-i18next";
+import { useTranslation } from "@/i18n";

435-453: Replace 'any' type with proper typing.

Using 'any' type reduces type safety. Consider using the generic type parameter T.

-{items.map((item: any, index) => {
+{items.map((item: T, index) => {

486-486: Simplify grid classes using Tailwind @apply.

Consider extracting repeated grid classes into a custom Tailwind class to follow DRY principles.

-<div className=" flex grid w-full gap-1 overflow-hidden bg-white p-4    sm:grid-cols-1 md:grid-cols-1 lg:grid-cols-5">
+<div className="resource-grid-layout">

Add to your Tailwind CSS file:

@layer components {
  .resource-grid-layout {
    @apply flex grid w-full gap-1 overflow-hidden bg-white p-4 sm:grid-cols-1 md:grid-cols-1 lg:grid-cols-5;
  }
}
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5e44297 and f3359e3.

📒 Files selected for processing (2)
  • public/locale/en.json (3 hunks)
  • src/components/Resource/ResourcePage.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • public/locale/en.json
🧰 Additional context used
📓 Learnings (1)
src/components/Resource/ResourcePage.tsx (1)
Learnt from: Jacobjeevan
PR: ohcnetwork/care_fe#9768
File: src/components/Resource/ResourcePage.tsx:80-89
Timestamp: 2025-01-20T09:11:54.138Z
Learning: In the care_fe project, useQuery and useMutation hooks have global error handlers. Additional error handlers should only be added when specific functionality is needed beyond the global handler. In such cases, prefer using built-in params like isSuccess and isError from useQuery/useMutation.
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: cypress-run (1)
  • GitHub Check: CodeQL-Build
🔇 Additional comments (2)
src/components/Resource/ResourcePage.tsx (2)

96-106: LGTM! View mode persistence implementation.

The implementation correctly persists and restores the view mode preference using localStorage, as discussed in previous review comments.


278-317: Well-structured generic component implementation!

The ResourceColumn component is well-implemented with proper type safety and clean separation of concerns.

Comment on lines +89 to +94
const exportAction = () => {
const data = query(routes.downloadResourceRequests, {
queryParams: { ...appliedFilters, csv: true },
})({ signal: new AbortController().signal });
return data ?? null;
};
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve request cancellation in exportAction.

The AbortController is created but never stored, making it impossible to cancel the request if needed.

 const exportAction = () => {
+  const controller = new AbortController();
   const data = query(routes.downloadResourceRequests, {
     queryParams: { ...appliedFilters, csv: true },
-  })({ signal: new AbortController().signal });
+  })({ signal: controller.signal });
   return data ?? null;
 };
📝 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
const exportAction = () => {
const data = query(routes.downloadResourceRequests, {
queryParams: { ...appliedFilters, csv: true },
})({ signal: new AbortController().signal });
return data ?? null;
};
const exportAction = () => {
const controller = new AbortController();
const data = query(routes.downloadResourceRequests, {
queryParams: { ...appliedFilters, csv: true },
})({ signal: controller.signal });
return data ?? null;
};

Comment on lines +399 to +413
<ExportButton
variant="secondary"
className=" bg-transparent shadow-none text-black rounded-full"
action={async () => {
const data = query(routes.downloadResourceRequests, {
queryParams: {
...formatFilter({ ...qParams, status: section.id }),
csv: true,
},
})({ signal: new AbortController().signal });
return data ?? null;
}}
filenamePrefix={`resource_requests_${section.id}`}
/>
</div>
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Fix request cancellation in ExportButton action.

Similar to the main exportAction, the AbortController is created but never stored.

 action={async () => {
+  const controller = new AbortController();
   const data = query(routes.downloadResourceRequests, {
     queryParams: {
       ...formatFilter({ ...qParams, status: section.id }),
       csv: true,
     },
-  })({ signal: new AbortController().signal });
+  })({ signal: controller.signal });
   return data ?? null;
 }}
📝 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
<ExportButton
variant="secondary"
className=" bg-transparent shadow-none text-black rounded-full"
action={async () => {
const data = query(routes.downloadResourceRequests, {
queryParams: {
...formatFilter({ ...qParams, status: section.id }),
csv: true,
},
})({ signal: new AbortController().signal });
return data ?? null;
}}
filenamePrefix={`resource_requests_${section.id}`}
/>
</div>
<ExportButton
variant="secondary"
className=" bg-transparent shadow-none text-black rounded-full"
action={async () => {
const controller = new AbortController();
const data = query(routes.downloadResourceRequests, {
queryParams: {
...formatFilter({ ...qParams, status: section.id }),
csv: true,
},
})({ signal: controller.signal });
return data ?? null;
}}
filenamePrefix={`resource_requests_${section.id}`}
/>
</div>

@manmeetnagii
Copy link
Contributor Author

manmeetnagii commented Jan 20, 2025

Check the previous review as well, missed one.

@Jacobjeevan Done 😅

@rithviknishad
Copy link
Member

Resources pages are going to be rebuilt anyways soon

@manmeetnagii manmeetnagii deleted the enhanced-resource-page branch January 22, 2025 18:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants