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

feature: Added services history section in device details page (10828) #10934

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from

Conversation

Yashgupta9330
Copy link

@Yashgupta9330 Yashgupta9330 commented Mar 2, 2025

Proposed Changes

Screen.Recording.2025-03-01.222211.mp4

@ohcnetwork/care-fe-code-reviewers

Merge Checklist

  • Add specs that demonstrate bug / test a new feature.
  • Update product documentation.
  • Ensure that UI text is kept in I18n files.
  • Prep screenshot or demo video for changelog entry, and attach it to issue.
  • Request for Peer Reviews
  • Completion of QA

Summary by CodeRabbit

  • New Features
    • Enhanced localization with updated key texts for service records, improving user clarity.
    • Introduced a service history section in device details, allowing users to view and manage maintenance records.
    • Added an interactive interface for adding and editing service records, streamlining device upkeep management.
    • New components for service history management, including DeviceServiceHistory, ServiceHistorySheet, and ServiceHistoryForm, enhancing user interaction with service records.

@Yashgupta9330 Yashgupta9330 requested a review from a team as a code owner March 2, 2025 09:06
Copy link
Contributor

coderabbitai bot commented Mar 2, 2025

Walkthrough

The pull request introduces new localization keys in the English JSON for service record-related UI elements. It adds a new component, DeviceServiceHistory, to the device detail page, along with its supporting components ServiceHistorySheet and ServiceHistoryForm for managing service record creation and editing. Additionally, new TypeScript interfaces and API methods have been added to handle service history data. These changes enhance both the user interface and the underlying data management for device maintenance records.

Changes

File(s) Involved Summary of Changes
public/locale/en.json Added key-value pairs for service record information (service date, history, notes, etc.).
src/pages/Facility/settings/devices/DeviceDetail.tsx, src/pages/Facility/settings/devices/components/DeviceServiceHistory.tsx, src/pages/Facility/settings/devices/components/ServiceHistorySheet.tsx, src/pages/Facility/settings/devices/components/ServiceHistoryForm.tsx Introduced new components for displaying and managing device service history; integrated UI sections for listing records and forms for add/edit actions.
src/types/device/device.ts, src/types/device/deviceApi.ts Added new interfaces for service history entries and extended the device API with methods (list, retrieve, create, update) for service records.

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant D as DeviceDetail
    participant DHS as DeviceServiceHistory
    participant SHEET as ServiceHistorySheet
    participant API as deviceApi

    U->>D: Open Device Detail Page
    D->>DHS: Render service history component with facilityId & deviceId
    DHS->>API: Fetch service history list
    API-->>DHS: Return service history data
    U->>DHS: Click on add/edit service record
    DHS->>SHEET: Open service history sheet/modal
    SHEET->>API: Submit create/update request
    API-->>SHEET: Confirm mutation
    SHEET-->>DHS: Trigger refresh of service history list
Loading

Suggested labels

tested, needs review

Suggested reviewers

  • rithviknishad
  • Jacobjeevan

Poem

I'm a rabbit, hopping with glee,
New keys and components for all to see.
Service histories now sing in code,
With forms and APIs lightening the load.
A joyful leap into fresh UI delight!
🐰🌟 Hop on, dear devs, code through the night!
Celebrate change with a merry byte!


📜 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 407f17d and bae5da5.

📒 Files selected for processing (6)
  • public/locale/en.json (1 hunks)
  • src/pages/Facility/settings/devices/components/DeviceServiceHistory.tsx (1 hunks)
  • src/pages/Facility/settings/devices/components/ServiceHistoryForm.tsx (1 hunks)
  • src/pages/Facility/settings/devices/components/ServiceHistorySheet.tsx (1 hunks)
  • src/types/device/device.ts (1 hunks)
  • src/types/device/deviceApi.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/types/device/device.ts
  • src/pages/Facility/settings/devices/components/DeviceServiceHistory.tsx
  • public/locale/en.json
🔇 Additional comments (11)
src/pages/Facility/settings/devices/components/ServiceHistorySheet.tsx (2)

15-21: The interface definition is well-structured.

The ServiceHistorySheetProps interface is clearly defined with appropriate prop types, making the component's API clear and type-safe. Good job using the ServiceHistory type instead of any for the serviceRecord prop.


23-51: Well-implemented component with proper internationalization.

The component is well-structured, with clear separation of concerns and proper use of UI components. It correctly uses the translation function for all user-facing text, ensuring good internationalization support.

src/types/device/deviceApi.ts (2)

4-10: Good job adding proper type imports.

The imports have been updated to include the necessary types for service history functionality, which enhances type safety.


55-78:

❓ Verification inconclusive

Consider standardizing API path parameter naming conventions.

The path parameters in the service history endpoints use facility_external_id and device_external_id, while other endpoints in this file use facility_id and id. While this might be required by the API documentation (as mentioned in previous comments), it creates an inconsistency in the codebase.

For better maintainability, consider either:

  1. Standardizing on one naming convention if possible
  2. Adding a comment explaining why these endpoints use different naming conventions

🏁 Script executed:

#!/bin/bash
# Check if other API files follow similar naming patterns for consistency

echo "Checking for other API path param naming patterns:"
rg -A 1 "path: \"/api/v\d/" --glob "src/types/**/*.ts" | grep -v "facility_external_id" | head -n 20

Length of output: 1331


Standardize API Path Parameter Naming for Consistency

We've observed that the serviceHistory endpoints in src/types/device/deviceApi.ts use {facility_external_id} and {device_external_id}, which contrasts with similar endpoints in other parts of the codebase (for example, those in src/types/questionnaire/questionnaireApi.ts) that use {id}. For better maintainability, please consider:

  • Option 1: Renaming the path parameters to match your other endpoints (e.g., change {facility_external_id} to {facility_id} and {device_external_id} to {id}) if this aligns with the API documentation.
  • Option 2: If the current naming is mandated by the API specification, add a clear comment to explain the deviation.
src/pages/Facility/settings/devices/components/ServiceHistoryForm.tsx (7)

56-62: Form initialization looks good.

The form is initialized with empty values, which is appropriate for production use.


85-87: Enhance error handling with user feedback.

The error handling only logs to console without providing feedback to the user. Consider adding a toast notification or form error message.

onError: (error) => {
  console.error("Failed to create service record:", error);
+  // Add user-facing error notification
+  toast({
+    title: t("error_title"),
+    description: t("error_create_service_record"),
+    variant: "destructive",
+  });
},

Also applies to: 105-107


117-129: Good implementation of form submission logic.

The form submission logic correctly handles both create and update scenarios, and properly preserves existing meta data when updating a service record.


71-74: Form reset uses empty values correctly.

The form reset logic correctly uses an empty string for the note field, which is appropriate for production use.


199-207: Excellent UX with contextual button labels.

The submit button text dynamically changes based on both the operation type (create/update) and the current state (pending/ready), which provides clear feedback to the user.


64-76: Consider adding validation for future dates.

The form allows selecting future dates for service records, which might not be desired in a real-world scenario where services typically happened in the past or present.

Consider if you want to limit the date picker to only past dates or today:

<Calendar
  mode="single"
  selected={field.value}
  onSelect={field.onChange}
  initialFocus
+ disabled={(date) => date > new Date()}
/>

89-91:

❓ Verification inconclusive

Check invalidation query key.

The query invalidation uses the key ["device", facilityId, deviceId], but it's not immediately clear if this will invalidate the service history list. Consider also invalidating the service history list query explicitly.


🏁 Script executed:

#!/bin/bash
# Check query keys used for service history listing

echo "Checking for service history query keys:"
rg "queryKey: \[.*serviceHistory" --glob "src/**/*.tsx"

Length of output: 426


Clarify Query Invalidation for Service History Refresh

The current invalidation call uses the key ["device", facilityId, deviceId], but our search shows that the service history queries are registered with the key ["device", facilityId, deviceId, "serviceHistory"]. Although React Query typically performs partial matching (thus invalidating queries that extend the provided key), please verify that this behavior meets the intended refresh requirements for the service history list. If the service history list isn’t refreshing as expected, consider explicitly invalidating it, for example:

queryClient.invalidateQueries({
  queryKey: ["device", facilityId, deviceId, "serviceHistory"],
});
  • File: src/pages/Facility/settings/devices/components/ServiceHistoryForm.tsx
  • Action: Confirm whether the partial invalidation is sufficient or if an explicit invalidation of the service history key is needed.
✨ Finishing Touches
  • 📝 Generate Docstrings

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.
  • @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 Mar 2, 2025

Deploy Preview for care-ohc ready!

Name Link
🔨 Latest commit bae5da5
🔍 Latest deploy log https://app.netlify.com/sites/care-ohc/deploys/67c4b7ed43eadd000861fd9a
😎 Deploy Preview https://deploy-preview-10934.preview.ohc.network
📱 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.

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

🧹 Nitpick comments (3)
src/types/device/device.ts (1)

68-72: Consider making the meta field more type-safe.

While using Record<string, any> provides flexibility, it could lead to type safety issues. Consider defining a more specific structure for the meta field if the structure is known.

-  meta?: Record<string, any>;
+  meta?: Record<string, string | number | boolean | null>;
src/pages/Facility/settings/devices/components/ServiceHistorySheet.tsx (1)

193-196: Add character limit and validation for note field.

The note textarea should have a maximum length to prevent excessively long entries.

  <Textarea
    placeholder={t("service_notes_enter")}
    {...field}
    rows={5}
+   maxLength={500}
  />

Also, update the form schema:

const formSchema = z.object({
-  note: z.string().min(1, { message: "Notes are required" }),
+  note: z.string().min(1, { message: "Notes are required" }).max(500, { message: "Notes cannot exceed 500 characters" }),
  serviced_on: z.date({ required_error: "Service date is required" }),
});
src/types/device/deviceApi.ts (1)

56-82: Consider using type annotations instead of type assertions for better type safety.

The service history API methods use type assertions with empty objects (e.g., {} as ServiceHistoryResponse). While this works, it's generally better practice to use type annotations for better type safety.

-      TRes: {} as ServiceHistoryListResponse,
+      TRes: Type<ServiceHistoryListResponse>(),
-      TReq: {},
+      TReq: Type<void>(),

-      TRes: {} as ServiceHistoryResponse,
+      TRes: Type<ServiceHistoryResponse>(),
-      TReq: {},
+      TReq: Type<void>(),

-      TRes: {} as ServiceHistoryResponse,
+      TRes: Type<ServiceHistoryResponse>(),
-      TReq: {} as ServiceHistoryCreateUpdateRequest,
+      TReq: Type<ServiceHistoryCreateUpdateRequest>(),

-      TRes: {} as ServiceHistoryResponse,
+      TRes: Type<ServiceHistoryResponse>(),
-      TReq: {} as ServiceHistoryCreateUpdateRequest,
+      TReq: Type<ServiceHistoryCreateUpdateRequest>(),

This matches the pattern used in other API methods in this file and provides more consistent type handling.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 957f5e5 and e13f7d9.

📒 Files selected for processing (6)
  • public/locale/en.json (2 hunks)
  • src/pages/Facility/settings/devices/DeviceDetail.tsx (2 hunks)
  • src/pages/Facility/settings/devices/components/DeviceServiceHistory.tsx (1 hunks)
  • src/pages/Facility/settings/devices/components/ServiceHistorySheet.tsx (1 hunks)
  • src/types/device/device.ts (1 hunks)
  • src/types/device/deviceApi.ts (2 hunks)
🔇 Additional comments (9)
src/pages/Facility/settings/devices/DeviceDetail.tsx (2)

41-41: Good addition of the DeviceServiceHistory component import.

The import is correctly placed with other component imports.


372-372: Properly integrated the DeviceServiceHistory component.

The DeviceServiceHistory component is correctly added to the UI with the required props (facilityId and deviceId).

src/types/device/device.ts (2)

53-59: Type definition for ServiceHistoryResponse looks good.

The interface properly defines the structure for a service history record with appropriate fields.


61-66: Well-structured pagination interface for service history.

The ServiceHistoryListResponse interface follows the standard pagination pattern with count, next, previous, and results fields.

src/pages/Facility/settings/devices/components/DeviceServiceHistory.tsx (1)

118-118: Good use of fallback for translation.

Providing a fallback text in case the translation key is missing is a good practice.

src/types/device/deviceApi.ts (2)

4-11: Good addition of new service history types to import statement.

The import statement has been updated to include the new types needed for the service history API functionality. This is a clean approach to organizing the imports.


85-85: Export statement updated correctly.

The export statement has been properly updated to export the deviceApi constant, making the API accessible to other modules.

public/locale/en.json (2)

505-509: Good addition of reusable button labels.

These button labels ("Cancel", "Save", "Saving...", etc.) are well-structured and can be reused across the application, promoting consistency in the UI.


2191-2198: Service history labels added correctly.

The service history-related labels are descriptive and follow the established naming conventions of the project. They adequately cover all the UI needs for the new service history functionality.

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

🧹 Nitpick comments (3)
src/pages/Facility/settings/devices/components/ServiceHistorySheet.tsx (3)

48-51: Localize validation error messages.

The form schema contains hardcoded error messages which should be internationalized for consistency with the rest of the application.

const formSchema = z.object({
-  note: z.string().min(1, { message: "Notes are required" }),
-  serviced_on: z.date({ required_error: "Service date is required" }),
+  note: z.string().min(1, { message: t("error_notes_required") }),
+  serviced_on: z.date({ required_error: t("error_service_date_required") }),
});

Don't forget to add these new translation keys to your localization files.


180-185: Add date constraints to the Calendar component.

The Calendar component currently allows selection of any date, including future dates. Consider adding constraints appropriate for service records (e.g., preventing future dates).

<Calendar
  mode="single"
  selected={field.value}
  onSelect={field.onChange}
  initialFocus
+  disabled={(date) => date > new Date()}
+  fromDate={new Date(2000, 0, 1)} // Set a reasonable minimum date
/>

140-140: Extract loading state to a more descriptive variable name.

The variable name isPending is correct but could be more descriptive about what operation is pending.

-const isPending = createMutation.isPending || updateMutation.isPending;
+const isSubmitting = createMutation.isPending || updateMutation.isPending;

// Then update usage:
-<Button type="submit" disabled={isPending}>
-  {isPending
+<Button type="submit" disabled={isSubmitting}>
+  {isSubmitting
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between e13f7d9 and 407f17d.

📒 Files selected for processing (2)
  • src/pages/Facility/settings/devices/components/DeviceServiceHistory.tsx (1 hunks)
  • src/pages/Facility/settings/devices/components/ServiceHistorySheet.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/pages/Facility/settings/devices/components/DeviceServiceHistory.tsx
🔇 Additional comments (5)
src/pages/Facility/settings/devices/components/ServiceHistorySheet.tsx (5)

114-116: Improve error handling with user feedback.

Similar to the create mutation, the update mutation should provide user feedback on errors.

onError: (error) => {
  console.error("Failed to update service record:", error);
+  // Add user-facing error notification
+  toast({
+    title: t("error_title"),
+    description: t("error_update_service_record"),
+    variant: "destructive",
+  });
},

36-38: LGTM - Good use of type imports and API structure.

The component properly imports and uses the correct types from device APIs, making it type-safe and maintainable.


73-85: LGTM - Well-implemented form reset logic.

The useEffect hook properly handles form reset logic for both new and existing service records, ensuring the form is in the correct state.


126-138: LGTM - Effective submission handler with metadata preservation.

The onSubmit function correctly handles both creation and update cases while preserving metadata.


209-226: LGTM - Well-implemented button states with internationalization.

The form buttons correctly handle loading states and use translation keys for text, making the UI responsive and properly localized.

Comment on lines +59 to +60
path: "/api/v1/facility/{facility_external_id}/device/{device_external_id}/service_history/",
method: HttpMethod.GET,
Copy link
Member

Choose a reason for hiding this comment

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

this is javascript; follow naming conventions;

Suggested change
path: "/api/v1/facility/{facility_external_id}/device/{device_external_id}/service_history/",
method: HttpMethod.GET,
path: "/api/v1/facility/{facilityId}/device/{deviceId}/service_history/",
method: HttpMethod.GET,

Copy link
Author

Choose a reason for hiding this comment

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

but i am passsing also like these and in api documentation these names facility_external_id are there
const { data: serviceHistory, isLoading } = useQuery({
queryKey: ["device", facilityId, deviceId, "serviceHistory"],
queryFn: query(deviceApi.serviceHistory.list, {
pathParams: {
facility_external_id: facilityId,
device_external_id: deviceId,
},
}),

Comment on lines +89 to +93
<TableRow>
<TableHead>{t("service_date")}</TableHead>
<TableHead>{t("service_notes")}</TableHead>
<TableHead className="text-right">{t("actions")}</TableHead>
</TableRow>
Copy link
Member

Choose a reason for hiding this comment

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

use TableSkeleton instead

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add support for recording service history for devices
2 participants