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

Migrated Scribe to a CARE App + Context #8469

Merged
merged 40 commits into from
Nov 13, 2024
Merged

Migrated Scribe to a CARE App + Context #8469

merged 40 commits into from
Nov 13, 2024

Conversation

shivankacker
Copy link
Member

@shivankacker shivankacker commented Sep 3, 2024

Proposed Changes

Moves Scribe to https://github.com/ohcnetwork/care_scribe_fe

Screen.Recording.2024-11-06.at.12.34.23.PM.mov

Requires care_scribe backend plugin pointing to ohcnetwork/care_scribe#12

Make sure to add the SCRIBE_ENABLED flag through Django Admin to your user

Requires the care_scribe_fe frontend appp. Add that by updating your env to include
REACT_ENABLED_APPS="ohcnetwork/care_livekit_fe,ohcnetwork/care_scribe_fe"

NOTE: Cannot update non arbitrary fields like symptoms, diagnoses for now.

@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

Release Notes

  • New Features

    • Introduced keyboard shortcut rendering functionality.
    • Added a custom hook for observing changes to DOM attributes, enhancing component interactivity.
    • Implemented a voice recording hook with improved microphone permission handling.
    • Enhanced date input component to reflect external value changes.
    • Improved dropdown components with better value synchronization and accessibility features.
    • Updated audio capture dialog to utilize a new voice recorder hook.
    • Enhanced functionality in the SymptomsBuilder component for better user interaction.
    • Updated DailyRounds component for improved form handling and validation.
  • Bug Fixes

    • Adjusted unselect radio input handling for better data representation.
    • Refined validation and threshold handling in text input fields.
  • Documentation

    • Expanded localization support with additional key-value pairs for improved user feedback.
  • Chores

    • Removed deprecated API routes related to the Scribe functionality.
    • Removed the Scribe component and associated functionalities.

@shivankacker shivankacker requested a review from a team as a code owner September 3, 2024 11:17
Copy link

netlify bot commented Sep 3, 2024

Deploy Preview for care-ohc ready!

Name Link
🔨 Latest commit 01bf5af
🔍 Latest deploy log https://app.netlify.com/sites/care-ohc/deploys/67346b29e27fef00088fc0db
😎 Deploy Preview https://deploy-preview-8469--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.

@shivankacker shivankacker added waiting for related PR a co-related detail PR is under construction and removed work-in-progress labels Sep 3, 2024
Copy link

github-actions bot commented Sep 3, 2024

👋 Hi, @shivankacker,
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.

@github-actions github-actions bot added the merge conflict pull requests with merge conflict label Sep 3, 2024
@shivankacker shivankacker added waiting for more data and removed waiting for related PR a co-related detail PR is under construction labels Sep 3, 2024
@github-actions github-actions bot added the stale label Sep 11, 2024
@github-actions github-actions bot removed the merge conflict pull requests with merge conflict label Sep 15, 2024
Copy link

cypress bot commented Sep 15, 2024

CARE    Run #3898

Run Properties:  status check passed Passed #3898  •  git commit 01bf5afea8: Migrated Scribe to a CARE App + Context
Project CARE
Branch Review scribe-context
Run status status check passed Passed #3898
Run duration 04m 49s
Commit git commit 01bf5afea8: Migrated Scribe to a CARE App + Context
Committer Shivank Kacker
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 0
Tests that did not run due to a developer annotating a test with .skip  Pending 0
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 126
View all changes introduced in this branch ↗︎

@github-actions github-actions bot added merge conflict pull requests with merge conflict and removed stale labels Sep 16, 2024
Copy link

👋 Hi, @shivankacker,
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.

@github-actions github-actions bot added the stale label Sep 25, 2024
@bodhish
Copy link
Member

bodhish commented Oct 7, 2024

@shivankacker please close pending PR's before opening others.

@github-actions github-actions bot removed the stale label Oct 8, 2024
@shivankacker
Copy link
Member Author

@bodhish working on this currently

@github-actions github-actions bot added Deploy-Failed Deplyment is not showing preview and removed merge conflict pull requests with merge conflict labels Nov 6, 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 (30)
cypress/e2e/patient_spec/PatientBedManagement.cy.ts (1)

Line range hint 6-54: Consider enhancing test robustness and coverage.

While the test implementation is solid, consider these improvements:

  1. Add data cleanup in afterEach to ensure test isolation
  2. Add error handling for failed bed assignments
  3. Add test cases for edge scenarios:
    • Attempting to assign an already occupied bed
    • Handling network errors during bed assignment
    • Verifying bed status updates in real-time

Here's a suggested enhancement:

 afterEach(() => {
   cy.saveLocalStorage();
+  // Clean up assigned beds
+  cy.intercept('POST', '**/bed/clear/').as('clearBed');
+  patientPage.visitPatient(switchPatientOne);
+  patientLogupdate.clickSwitchBed();
+  cy.get('#clear-button').click();
+  cy.wait('@clearBed');
+  
+  patientPage.visitPatient(switchPatientTwo);
+  patientLogupdate.clickSwitchBed();
+  cy.get('#clear-button').click();
+  cy.wait('@clearBed');
 });

+it("Should handle bed assignment failures gracefully", () => {
+  // Simulate network error
+  cy.intercept('POST', '**/bed/assign/', {
+    statusCode: 500,
+    body: { detail: 'Internal Server Error' }
+  }).as('failedAssignment');
+
+  patientPage.visitPatient(switchPatientOne);
+  patientLogupdate.clickSwitchBed();
+  patientLogupdate.selectBed(switchBedOne);
+  
+  // Verify error handling
+  cy.wait('@failedAssignment');
+  cy.verifyNotification("Failed to assign bed");
+});
cypress/e2e/patient_spec/PatientDoctorConnect.cy.ts (2)

Line range hint 1-14: Consider moving test data to fixtures.

The test data (patient name, user roles) should be moved to a fixture file for better maintainability and reusability. This would make it easier to update test data and share it across different test files.

Example implementation:

// cypress/fixtures/doctor-connect.json
{
  "patientName": "Dummy Patient 11",
  "users": {
    "doctor": "Dev Doctor",
    "nurse": "Dev Staff",
    "teleIcuDoctor": "Dev Doctor Two"
  }
}

// In test file
let testData: any;

before(() => {
  cy.fixture('doctor-connect').then((data) => {
    testData = data;
  });
  loginPage.loginAsDistrictAdmin();
  cy.saveLocalStorage();
});

Line range hint 29-54: Split the test case into multiple focused scenarios.

The current test case violates the single responsibility principle by testing multiple features (user visibility, copy functionality, icon presence, and sorting) in one test. This makes it harder to debug failures and maintain the test.

Consider splitting into these focused test cases:

it("should display users under correct sections", () => {
  patientPage.visitPatient(testData.patientName);
  doctorconnect.clickDoctorConnectButton();
  cy.verifyContentPresence("#doctor-connect-home-doctor", [testData.users.doctor]);
  cy.verifyContentPresence("#doctor-connect-home-nurse", [testData.users.nurse]);
  cy.verifyContentPresence("#doctor-connect-remote-doctor", [testData.users.teleIcuDoctor]);
});

it("should copy phone number correctly", () => {
  patientPage.visitPatient(testData.patientName);
  doctorconnect.clickDoctorConnectButton();
  doctorconnect.CopyFunctionTrigger();
  doctorconnect.clickCopyPhoneNumber("#doctor-connect-home-doctor", testData.users.doctor);
  doctorconnect.verifyCopiedContent();
});

it("should display communication icons", () => {
  patientPage.visitPatient(testData.patientName);
  doctorconnect.clickDoctorConnectButton();
  doctorconnect.verifyIconVisible("#whatsapp-icon");
  doctorconnect.verifyIconVisible("#phone-icon");
});

it("should filter users by role correctly", () => {
  patientPage.visitPatient(testData.patientName);
  doctorconnect.clickDoctorConnectButton();
  
  doctorconnect.clickUsersSortBy("Doctor");
  cy.verifyContentPresence("#doctor-connect-home-doctor", [testData.users.doctor]);
  
  doctorconnect.clickUsersSortBy("Nurse");
  cy.verifyContentPresence("#doctor-connect-home-nurse", [testData.users.nurse]);
  
  doctorconnect.clickUsersSortBy("TeleICU Doctor");
  cy.verifyContentPresence("#doctor-connect-remote-doctor", [testData.users.teleIcuDoctor]);
});
cypress/e2e/resource_spec/ResourcesHomepage.cy.ts (4)

Line range hint 5-11: Consider moving test data to a separate constants file.

The phone number constant could be moved to a shared test data file to maintain consistency across tests and make updates easier.

- const phone_number = "9999999999";

Create a new file cypress/fixtures/testData.ts:

export const TEST_PHONE_NUMBER = "9999999999";

Line range hint 39-63: Enhance resource request creation test reliability.

The resource request creation test could be flaky due to the search dependency. Consider these improvements:

  1. Add retry ability for the search
  2. Add more specific assertions for the facility search results
  3. Include error scenarios
 it("Create a resource request", () => {
   cy.visit("/facility");
-  cy.get("#search").click().type("dummy facility 40");
+  cy.get("#search")
+    .click()
+    .type("dummy facility 40")
+    .should("have.value", "dummy facility 40");
+
   cy.intercept("GET", "**/api/v1/facility/**").as("loadFacilities");
-  cy.get("#facility-details").click();
+  cy.get("#facility-details")
+    .should("be.visible")
+    .and("contain.text", "dummy facility 40")
+    .click();
+
   cy.wait("@loadFacilities").its("response.statusCode").should("eq", 200);
+  
+  // Verify facility details are loaded
+  cy.get("body").should("not.contain.text", "Loading...");

Line range hint 1-89: Consider adding more comprehensive test coverage.

The test suite could benefit from additional scenarios:

  1. Error handling cases (e.g., network errors, validation errors)
  2. Accessibility checks for the resource page
  3. Verification of UI elements and their states

Example additions:

it("Should handle network errors gracefully", () => {
  cy.intercept("GET", "**/api/v1/facility/**", {
    statusCode: 500,
    body: { message: "Internal Server Error" }
  }).as("failedRequest");
  
  // Test error handling
});

it("Should meet accessibility standards", () => {
  cy.visit("/resource");
  cy.injectAxe();
  cy.checkA11y();
});

Line range hint 65-77: Verify resource status updates more thoroughly.

The status update test should verify:

  1. Available status options
  2. Status change reflection in UI
  3. API payload correctness
 it("Update the status of resource", () => {
   cy.visit(createdResource);
+  // Verify available status options
+  const expectedStatuses = ["APPROVED", "REJECTED", "PENDING"];
   resourcePage.clickUpdateStatus();
+  cy.get("[data-testid='status-options']")
+    .should("be.visible")
+    .find("option")
+    .should("have.length", expectedStatuses.length)
+    .each(($el, index) => {
+      expect($el.text()).to.equal(expectedStatuses[index]);
+    });
+
+  // Intercept status update request
+  cy.intercept("PATCH", "**/api/v1/resource/**").as("updateStatus");
   resourcePage.updateStatus("APPROVED");
   resourcePage.clickSubmitButton();
+  
+  // Verify API request
+  cy.wait("@updateStatus").then((interception) => {
+    expect(interception.request.body.status).to.equal("APPROVED");
+  });
+
+  // Verify UI update
+  cy.get("[data-testid='resource-status']")
+    .should("be.visible")
+    .and("contain.text", "APPROVED");
+
   resourcePage.verifySuccessNotification(
     "Resource request updated successfully",
   );
 });
cypress/e2e/facility_spec/FacilityInventory.cy.ts (2)

1-4: Consider implementing a consistent import ordering pattern.

While moving the LoginPage import is harmless, consider organizing imports consistently (e.g., alphabetically) to improve maintainability.

-import FacilityPage from "../../pageobject/Facility/FacilityCreation";
-import FacilityHome from "../../pageobject/Facility/FacilityHome";
-import LoginPage from "../../pageobject/Login/LoginPage";
+import FacilityHome from "../../pageobject/Facility/FacilityHome";
+import FacilityPage from "../../pageobject/Facility/FacilityCreation";
+import LoginPage from "../../pageobject/Login/LoginPage";

Line range hint 28-94: Improve test reliability by following Cypress best practices.

Several improvements could make these tests more robust:

  1. Replace hard-coded cy.wait(3000) with proper Cypress commands:
-cy.wait(3000);
+cy.get('#element').should('be.visible');
  1. Standardize success message verification:
-facilityPage.verifySuccessNotification("Inventory created successfully");
-facilityPage.verifySuccessNotification("Minimum quantiy updated successfully");
+const successMessages = {
+  inventoryCreated: "Inventory created successfully",
+  minimumQuantityUpdated: "Minimum quantiy updated successfully"
+};
+facilityPage.verifySuccessNotification(successMessages.inventoryCreated);
  1. Make element visibility checks more robust:
-if ($body.find("#update-minimum-quantity").is(":visible")) {
+cy.get('body').then(($body) => {
+  const updateBtn = $body.find("#update-minimum-quantity");
+  if (updateBtn.length && updateBtn.is(":visible")) {
src/Utils/useSegmentedRecorder.ts (2)

11-11: Remove redundant comment.

The variable name microphoneAccess is self-explanatory, making the inline comment "New state" unnecessary.

-  const [microphoneAccess, setMicrophoneAccess] = useState(false); // New state
+  const [microphoneAccess, setMicrophoneAccess] = useState(false);

130-130: Remove redundant comment.

The inline comment "Return microphoneAccess" is unnecessary as the code is self-documenting.

-    microphoneAccess, // Return microphoneAccess
+    microphoneAccess,
cypress/e2e/patient_spec/PatientFileUpload.ts (5)

Line range hint 4-28: Consider extracting test constants to a separate file.

The test setup follows good practices with page objects and proper test isolation. However, the test constants (patient names, file names) could be moved to a separate configuration file for better maintainability and reuse across other test files.

+ // testData/patients.ts
+ export const TEST_PATIENTS = {
+   PATIENT_ONE: "Dummy Patient 3",
+   PATIENT_TWO: "Dummy Patient 4",
+   PATIENT_THREE: "Dummy Patient 5"
+ };
+ 
+ export const TEST_FILES = {
+   AUDIO_NAME: "cypress audio",
+   FILE_NAME: "cypress name",
+   MODIFIED_NAME: "cypress modified name"
+ };

Line range hint 30-46: Add verification for audio file format and content.

The audio recording test should verify the format and basic properties of the recorded audio file. Also consider adding error scenarios for when audio recording fails.

 it("Record an Audio and download the file", () => {
   patientPage.visitPatient(patientNameOne);
   visitPatientFileUploadSection.call(patientFileUpload);
   patientFileUpload.recordAudio();
   patientFileUpload.typeAudioName(cypressAudioName);
   patientFileUpload.clickUploadAudioFile();
   cy.verifyNotification("File Uploaded Successfully");
   patientFileUpload.verifyUploadFilePresence(cypressAudioName);
   cy.get("button").contains("Download").click();
   cy.verifyNotification("Downloading file...");
+  // Verify audio file properties
+  cy.get('[data-testid="audio-player"]').should('have.attr', 'src')
+    .and('match', /^blob:http/);
+  // Verify file download
+  cy.readFile('cypress/downloads/' + cypressAudioName)
+    .should('exist');
 });

Line range hint 48-64: Add error scenarios for file upload test.

The file upload test should include scenarios for invalid file types, large files, and network failures. Also verify the archived file's accessibility state.

 it("Upload a File and archive it", () => {
   patientPage.visitPatient(patientNameTwo);
   visitPatientFileUploadSection.call(patientFileUpload);
+  // Test invalid file type
+  patientFileUpload.uploadFile('invalid.exe');
+  cy.verifyNotification("Invalid file type");
+
+  // Test file size limit
+  patientFileUpload.uploadFile('large.pdf');
+  cy.verifyNotification("File size exceeds limit");
+
   patientFileUpload.uploadFile();
   patientFileUpload.typeFileName(cypressFileName);
   patientFileUpload.clickUploadFile();
   cy.verifyNotification("File Uploaded Successfully");
   cy.closeNotification();
   patientFileUpload.verifyUploadFilePresence(cypressFileName);
   patientFileUpload.archiveFile();
   patientFileUpload.clickSaveArchiveFile();
   cy.verifyNotification("File archived successfully");
   patientFileUpload.verifyArchiveFile(cypressFileName);
+  // Verify archived file is not editable
+  patientFileUpload.verifyFileRenameOption(false);
 });

Line range hint 66-115: Enhance user permission test coverage.

The permission test should verify additional operations like file deletion and archival permissions. Also consider testing with more user roles and edge cases.

 it("User-level Based Permission for File Modification", () => {
   loginPage.login("dummynurse1", "Coronasafe@123");
   cy.reload();
   patientPage.visitPatient(patientNameThree);
   visitPatientFileUploadSection.call(patientFileUpload);
   patientFileUpload.uploadFile();
   patientFileUpload.typeFileName(cypressFileName);
   patientFileUpload.clickUploadFile();
   cy.verifyNotification("File Uploaded Successfully");
   cy.closeNotification();
   patientFileUpload.verifyUploadFilePresence(cypressFileName);
+  // Verify additional permissions
+  patientFileUpload.verifyDeleteOption(false);
+  patientFileUpload.verifyArchiveOption(false);
+
   // ... existing permission checks ...
+
+  // Test with additional user roles
+  loginPage.login("doctor1", "Coronasafe@123");
+  cy.reload();
+  patientFileUpload.verifyUploadFilePresence(cypressFileName);
+  patientFileUpload.verifyFileRenameOption(true);
+  patientFileUpload.verifyDeleteOption(true);
+  patientFileUpload.verifyArchiveOption(true);
 });

Line range hint 123-131: Add cross-browser testing configuration.

The tests should be configured to run across different browsers to ensure consistent behavior. Also consider adding parallel test execution for better performance.

+ // cypress.config.ts
+ export default {
+   e2e: {
+     browsers: ['chrome', 'firefox', 'edge'],
+     // Enable parallel execution
+     parallel: true,
+     // Group similar tests
+     testIsolation: false
+   }
+ };
cypress/e2e/assets_spec/AssetsManage.cy.ts (3)

Line range hint 1-120: Consider enhancing test maintainability and reliability.

While reviewing the entire test suite, I noticed some opportunities for improvement:

  1. Test data management:

    • Hard-coded values like "Dummy Facility 40" should be moved to test fixtures
    • Date manipulation could be centralized in a helper
  2. Test isolation:

    • Consider using cy.intercept() to mock network requests
    • Add cleanup in afterEach to ensure consistent state
  3. Error handling:

    • Add timeout configurations for slow operations
    • Include error assertions for negative scenarios

Example implementation for test data management:

// fixtures/asset-data.json
{
  "facility": {
    "name": "Dummy Facility 40"
  },
  "asset": {
    "name": "Dummy Camera",
    "initialLocation": "Camera Location",
    "newLocation": "Dummy Location 1"
  }
}

// support/commands.ts
Cypress.Commands.add('loadAssetTestData', () => {
  cy.fixture('asset-data.json').as('testData');
});

// Example usage in test
beforeEach(() => {
  cy.loadAssetTestData();
  // ... other setup
});

it('Verify Asset Warranty Expiry Label', function() {
  const { asset } = this.testData;
  assetSearchPage.typeSearchKeyword(asset.name);
  // ... rest of the test
});

Line range hint 8-13: Move date utility to a dedicated helper file.

The addDaysToDate function should be moved to a shared helper file for reusability across test files.

// support/helpers/date.ts
export const addDaysToDate = (numberOfDays: number): string => {
  const inputDate = new Date();
  inputDate.setDate(inputDate.getDate() + numberOfDays);
  return inputDate.toISOString().split('T')[0];
};

// Import in test file
import { addDaysToDate } from '../../support/helpers/date';

Line range hint 36-65: Enhance warranty expiry test with data-driven approach.

The warranty expiry test could be more maintainable using a data-driven approach.

const warrantyTestCases = [
  { days: 100, expectedLabel: '' },        // > 3 months
  { days: 80, expectedLabel: '3 months' }, // < 3 months
  { days: 20, expectedLabel: '1 month' },  // < 1 month
  { days: 100, expectedLabel: '' }         // Reset case
];

it('Verify Asset Warranty Expiry Label', () => {
  assetSearchPage.typeSearchKeyword(assetname);
  assetSearchPage.pressEnter();
  assetSearchPage.verifyBadgeContent(assetname);
  assetSearchPage.clickAssetByName(assetname);

  warrantyTestCases.forEach(({ days, expectedLabel }) => {
    assetPage.clickupdatedetailbutton();
    assetPage.scrollintoWarrantyDetails();
    assetPage.enterWarrantyExpiryDate(addDaysToDate(days));
    assetPage.clickassetupdatebutton();
    assetPage.verifyWarrantyExpiryLabel(expectedLabel);
  });
});
cypress/e2e/facility_spec/FacilityHomepage.cy.ts (1)

Line range hint 89-97: Consider enhancing pagination test coverage.

While the basic pagination tests are good, consider adding test cases for:

  • Edge cases (first/last page)
  • Items per page changes
  • Total items count verification
  • Page number validation

Example enhancement:

it("handles pagination edge cases", () => {
  assetPagination.navigateToLastPage();
  assetPagination.verifyNextButtonDisabled();
  assetPagination.navigateToFirstPage();
  assetPagination.verifyPreviousButtonDisabled();
  assetPagination.changeItemsPerPage(50);
  assetPagination.verifyItemsPerPageApplied(50);
});
cypress/e2e/users_spec/UsersCreation.cy.ts (4)

Line range hint 1-200: Consider enhancing test coverage for iPhone-specific scenarios.

Given that Issue #8227 mentions iPhone-specific malfunctions, it would be valuable to add test cases that specifically verify the application's behavior on iPhone viewports.

Consider adding:

it("should work correctly on iPhone viewport", () => {
  cy.viewport('iphone-x');
  // Test user creation flow
  // Test profile updates
  // Verify any audio-related functionality
});

Line range hint 19-31: Consider extracting the makeid utility function.

The makeid function is a utility that could be reused across other test files. Consider moving it to a shared utilities file.

Move this to cypress/pageobject/utils/constants.ts:

export const makeid = (length: number) => {
  let result = "";
  const characters = "abcdefghijklmnopqrstuvwxyz0123456789";
  const charactersLength = characters.length;
  for (let i = 0; i < length; i++) {
    result += characters.charAt(Math.floor(Math.random() * charactersLength));
  }
  return result;
};

Line range hint 32-35: Consider using test data management for user lists.

The hardcoded array of users could be better managed through test data fixtures.

Consider creating a fixture file cypress/fixtures/users.json:

{
  "alreadyLinkedUsers": ["devdoctor", "devstaff2", "devdistrictadmin"]
}

Then import it in the test:

let users;
before(() => {
  cy.fixture('users').then((data) => {
    users = data;
  });
});

Line range hint 36-50: Consider using an enum for error messages.

The error message arrays could be better managed using TypeScript enums or constants in a separate file.

Consider creating cypress/constants/errorMessages.ts:

export enum UserCreationErrors {
  USER_TYPE = "Please select the User Type",
  PHONE_NUMBER = "Please enter valid phone number",
  // ... other messages
}

export enum ProfileErrors {
  REQUIRED = "This field is required",
  PHONE_NUMBER = "Please enter valid phone number"
}
cypress/e2e/patient_spec/PatientRegistration.cy.ts (4)

Line range hint 9-31: Consider improving date handling and age calculation.

The current implementation could be enhanced for better maintainability and robustness:

  1. The hardcoded year value could lead to maintenance issues
  2. Date calculations could benefit from a more robust approach

Consider this improvement:

-const yearOfBirth = "2001";
+const TEST_YEAR_OF_BIRTH = "2001";  // Make the constant name more descriptive
 
 const calculateAge = () => {
-  const currentYear = new Date().getFullYear();
-  return currentYear - parseInt(yearOfBirth);
+  const today = new Date();
+  const birthDate = new Date(`${TEST_YEAR_OF_BIRTH}-01-01`);
+  let age = today.getFullYear() - birthDate.getFullYear();
+  const monthDiff = today.getMonth() - birthDate.getMonth();
+  if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
+    age--;
+  }
+  return age;
 };

Line range hint 32-329: Enhance test organization and error coverage.

While the test cases are comprehensive, consider these improvements:

  1. Group test data setup into a separate fixture file
  2. Add negative test cases for form validation
  3. Add assertions for error states in the form fields

Create a new fixture file cypress/fixtures/patient-registration.json:

{
  "validPatient": {
    "name": "Patient With No Consultation",
    "gender": "Male",
    "updatedGender": "Female",
    "address": "Test Patient Address",
    // ... other test data
  },
  "invalidPatient": {
    "name": "",  // for validation testing
    "phone": "invalid",
    // ... invalid test data
  }
}

Then refactor the tests to use this fixture:

describe("Patient Creation with consultation", () => {
  let testData;
  
  before(() => {
    cy.fixture('patient-registration.json').then((data) => {
      testData = data;
    });
    // ... existing setup
  });

  // Add negative test case
  it("should show validation errors for invalid input", () => {
    patientPage.createPatient();
    patientPage.selectFacility(testData.validPatient.facility);
    patientPage.typePatientName(testData.invalidPatient.name);
    patientPage.typePatientPhoneNumber(testData.invalidPatient.phone);
    patientPage.clickCreatePatient();
    
    // Assert validation errors
    cy.get('[data-testid="name-error"]').should('be.visible');
    cy.get('[data-testid="phone-error"]').should('be.visible');
  });

  // ... existing test cases using testData
});

Line range hint 276-329: Enhance transfer test error scenarios.

The transfer test could be expanded to cover more error cases:

  1. Transfer with missing required fields
  2. Transfer with invalid patient data
  3. Network error handling

Add these test cases:

it("should handle transfer errors appropriately", () => {
  // Test missing required fields
  patientPage.createPatient();
  patientPage.selectFacility(patientTransferFacility);
  patientTransfer.clickTransferSubmitButton();
  cy.get('[data-testid="transfer-error"]').should('be.visible');

  // Test network error
  cy.intercept('POST', '/api/transfer', {
    statusCode: 500,
    body: { message: 'Internal Server Error' }
  });
  // ... complete the transfer flow
  cy.get('[data-testid="error-notification"]')
    .should('contain', 'Failed to transfer patient');
});

Line range hint 32-329: Add tests for Scribe integration.

Based on the PR objectives of migrating Scribe to CARE App, consider adding test cases for:

  1. Scribe interaction with existing form data
  2. Audio upload functionality (especially for iPhone)
  3. Integration between Scribe and patient registration

Would you like me to help create test cases for these scenarios? I can provide a detailed implementation that covers:

  • Scribe awareness of pre-filled form data
  • Audio upload validation
  • Cross-browser compatibility tests
public/locale/en.json (2)

254-255: Consider adding more voice-related localization keys for better UX.

The voice-related translations are clear and user-friendly. However, consider adding these additional keys to enhance the user experience:

  • Error states (e.g., "voice_recognition_failed", "network_error_during_recording")
  • Accessibility labels (e.g., "voice_record_button_aria_label")
  • Progress indicators (e.g., "processing_voice_input")

Also applies to: 490-491, 707-707, 1021-1021, 1078-1078, 1095-1096, 1160-1160, 1164-1164, 1191-1192, 1274-1274


334-334: Make the autofilled fields message more descriptive.

The "autofilled_fields" message could be more specific to provide better context to users.

Consider using a more descriptive message like:

-  "autofilled_fields": "Autofilled Fields",
+  "autofilled_fields": "Fields automatically filled from your health records",
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between df9a8d5 and 228856c.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (25)
  • cypress/e2e/assets_spec/AssetHomepage.cy.ts (1 hunks)
  • cypress/e2e/assets_spec/AssetsCreation.cy.ts (1 hunks)
  • cypress/e2e/assets_spec/AssetsManage.cy.ts (1 hunks)
  • cypress/e2e/facility_spec/FacilityCreation.cy.ts (1 hunks)
  • cypress/e2e/facility_spec/FacilityHomepage.cy.ts (1 hunks)
  • cypress/e2e/facility_spec/FacilityInventory.cy.ts (1 hunks)
  • cypress/e2e/facility_spec/FacilityManage.cy.ts (1 hunks)
  • cypress/e2e/patient_spec/PatientBedManagement.cy.ts (1 hunks)
  • cypress/e2e/patient_spec/PatientConsultationCreation.cy.ts (1 hunks)
  • cypress/e2e/patient_spec/PatientDoctorConnect.cy.ts (1 hunks)
  • cypress/e2e/patient_spec/PatientFileUpload.ts (1 hunks)
  • cypress/e2e/patient_spec/PatientLogUpdate.cy.ts (1 hunks)
  • cypress/e2e/patient_spec/PatientPrescription.cy.ts (1 hunks)
  • cypress/e2e/patient_spec/PatientRegistration.cy.ts (1 hunks)
  • cypress/e2e/resource_spec/ResourcesHomepage.cy.ts (1 hunks)
  • cypress/e2e/users_spec/UsersCreation.cy.ts (1 hunks)
  • cypress/e2e/users_spec/UsersManage.cy.ts (1 hunks)
  • public/locale/en.json (12 hunks)
  • src/Routers/AppRouter.tsx (1 hunks)
  • src/Utils/request/api.tsx (0 hunks)
  • src/Utils/useSegmentedRecorder.ts (5 hunks)
  • src/components/Common/BloodPressureFormField.tsx (1 hunks)
  • src/components/Common/DateInputV2.tsx (4 hunks)
  • src/components/Common/TemperatureFormField.tsx (2 hunks)
  • src/components/Common/prescription-builder/PrescriptionDropdown.tsx (1 hunks)
💤 Files with no reviewable changes (1)
  • src/Utils/request/api.tsx
✅ Files skipped from review due to trivial changes (7)
  • cypress/e2e/assets_spec/AssetHomepage.cy.ts
  • cypress/e2e/assets_spec/AssetsCreation.cy.ts
  • cypress/e2e/facility_spec/FacilityCreation.cy.ts
  • cypress/e2e/facility_spec/FacilityManage.cy.ts
  • cypress/e2e/patient_spec/PatientConsultationCreation.cy.ts
  • cypress/e2e/patient_spec/PatientLogUpdate.cy.ts
  • cypress/e2e/patient_spec/PatientPrescription.cy.ts
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/Routers/AppRouter.tsx
  • src/components/Common/BloodPressureFormField.tsx
  • src/components/Common/DateInputV2.tsx
  • src/components/Common/TemperatureFormField.tsx
  • src/components/Common/prescription-builder/PrescriptionDropdown.tsx
🔇 Additional comments (14)
cypress/e2e/patient_spec/PatientBedManagement.cy.ts (1)

1-4: LGTM! Import changes align with the migration.

The addition of PatientConsultationPage import is consistent with the PR's objective of migrating Scribe functionality.

cypress/e2e/patient_spec/PatientDoctorConnect.cy.ts (2)

Line range hint 16-28: LGTM! Well-structured test setup.

The test lifecycle hooks are properly implemented with good practices:

  • Login state persistence using localStorage
  • Proper cleanup of filters before each test
  • Clear URL verification

Line range hint 56-58: LGTM! Proper test cleanup.

The afterEach hook correctly persists the localStorage state for subsequent tests.

cypress/e2e/resource_spec/ResourcesHomepage.cy.ts (1)

1-3: LGTM! Import organization follows best practices.

The imports are now properly organized at the top of the file, improving code readability.

cypress/e2e/facility_spec/FacilityInventory.cy.ts (1)

Line range hint 5-27: Verify test stability after Scribe migration.

Since this PR involves migrating Scribe to a CARE app, please ensure these inventory management tests remain stable after the migration. Consider:

  1. Running these tests against both old and new environments
  2. Verifying that the page objects and selectors remain valid
  3. Documenting any environment-specific setup required for these tests
src/Utils/useSegmentedRecorder.ts (2)

Line range hint 29-41: Verify microphone access handling on iOS Safari.

Given the reported issues with iPhone (Issue #8227), please ensure this implementation works correctly on iOS Safari. Consider:

  1. iOS Safari requires user interaction before allowing media access
  2. Audio recording might need specific handling for iOS compatibility
#!/bin/bash
# Search for iOS-specific handling in the codebase
rg -i "ios|safari|useragent" --type ts --type tsx

104-113: ⚠️ Potential issue

Enhance error handling in startRecording.

The current implementation has several issues that need attention:

  1. The error message isn't internationalized
  2. The recorder state should be cleaned up on error
  3. The error handling at call sites might need to be documented

Apply these improvements:

 const startRecording = async () => {
   try {
     const newRecorder = await requestRecorder();
     setRecorder(newRecorder);
     setMicrophoneAccess(true);
     setIsRecording(true);
   } catch (error) {
     setMicrophoneAccess(false);
+    setRecorder(null);
+    setIsRecording(false);
-    throw new Error("Microphone access denied");
+    throw new Error(t("audio__permission_denied"));
   }
 };
cypress/e2e/assets_spec/AssetsManage.cy.ts (1)

2-2: LGTM! Import reordering looks good.

The reordering of imports maintains code organization without affecting functionality.

Also applies to: 5-5

cypress/e2e/facility_spec/FacilityHomepage.cy.ts (2)

2-5: LGTM! Import changes are clean and purposeful.

The addition of AssetPagination and reorganization of imports align well with the test file's functionality.


Line range hint 9-168: Test structure follows best practices, but consider adding Scribe-related tests.

The test suite is well-structured using the page object pattern and covers core facility homepage functionality comprehensively. However, given that this PR involves migrating Scribe functionality, consider adding test coverage for:

Let's verify if there are any Scribe-related tests in the codebase:

cypress/e2e/users_spec/UsersManage.cy.ts (2)

4-4: LGTM! Import change aligns with module organization.

The addition of UserPage import from UserSearch module follows good separation of concerns, keeping page object models organized by functionality.


Line range hint 1-168: Verify test coverage for Scribe migration.

The test suite thoroughly covers user management operations but should be verified against the new Scribe CARE app integration.

Let's check for any Scribe-related test coverage:

Consider adding specific test cases to verify:

  1. User permissions interaction with the new Scribe CARE app
  2. Integration points between user management and Scribe functionality
  3. Data consistency when users interact with Scribe features
cypress/e2e/users_spec/UsersCreation.cy.ts (1)

3-3: LGTM! Import statements are properly organized.

The imports are well-structured and the addition of generatePhoneNumber aligns with its usage in the test cases.

Also applies to: 5-5, 8-8

cypress/e2e/patient_spec/PatientRegistration.cy.ts (1)

1-7: LGTM! Well-organized imports.

The new imports for PatientTransfer and generatePhoneNumber are appropriately added and align with their usage in the test cases.

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 (7)
src/CAREUI/interactive/KeyboardShortcut.tsx (1)

81-98: Consider improving accessibility and error handling.

While the implementation is solid, consider these enhancements:

  1. Add error handling for invalid shortcut keys
  2. Improve screen reader support
  3. Consider mobile visibility strategy
 export function KeyboardShortcutKey(props: {
   shortcut: string[];
   useShortKeys?: boolean;
 }) {
   const { shortcut, useShortKeys } = props;
+  // Validate shortcut keys
+  const validShortcuts = shortcut.every(key => 
+    key in SHORTCUT_KEY_MAP || key.length > 0
+  );
+  
+  if (!validShortcuts) {
+    console.warn('Invalid shortcut keys provided:', shortcut);
+    return null;
+  }

   return (
-    <div className="hidden shrink-0 items-center md:flex">
+    <div 
+      className="hidden shrink-0 items-center md:flex"
+      role="group"
+      aria-label="Keyboard shortcuts"
+    >
       {shortcut.map((key, idx, keys) => (
         <Fragment key={idx}>
           <kbd 
+            aria-label={`Press ${SHORTCUT_KEY_MAP[key] || key}`}
             className="relative z-10 flex h-6 min-w-6 shrink-0 items-center justify-center rounded-md border border-b-4 border-secondary-400 bg-secondary-100 px-2 text-xs text-black"
           >
src/Utils/useVoiceRecorder.ts (6)

6-10: Consider using a single state object for related states.

The hook uses multiple independent state variables that are conceptually related. Consider combining them into a single state object to make state updates more atomic and prevent potential race conditions.

-  const [audioURL, setAudioURL] = useState("");
-  const [isRecording, setIsRecording] = useState(false);
-  const [recorder, setRecorder] = useState<MediaRecorder | null>(null);
-  const [blob, setBlob] = useState<Blob | null>(null);
-  const [waveform, setWaveform] = useState<number[]>([]); // Decibel waveform
+  const [state, setState] = useState({
+    audioURL: "",
+    isRecording: false,
+    recorder: null as MediaRecorder | null,
+    blob: null as Blob | null,
+    waveform: [] as number[],
+  });

16-20: Add explanatory comment for the recorder reset logic.

The purpose of this effect is not immediately clear. Consider adding a comment explaining why the recorder needs to be reset when recording stops and an audio URL exists.

 useEffect(() => {
+  // Reset recorder after successful recording to free up resources and prepare for next recording
   if (!isRecording && recorder && audioURL) {
     setRecorder(null);
   }
 }, [isRecording, recorder, audioURL]);

28-38: Enhance error handling with specific error types.

The error handling could be more specific to help users understand and resolve issues better. Consider categorizing errors based on their type (permission denied, device not found, etc.).

     } catch (error) {
+      let errorMessage = "Please grant microphone permission to record audio.";
+      if (error instanceof DOMException) {
+        switch (error.name) {
+          case 'NotAllowedError':
+            errorMessage = "Microphone access was denied. Please allow access in your browser settings.";
+            break;
+          case 'NotFoundError':
+            errorMessage = "No microphone found. Please connect a microphone and try again.";
+            break;
+          case 'NotReadableError':
+            errorMessage = "Could not access your microphone. Please check if it's properly connected.";
+            break;
+          default:
+            errorMessage = `Microphone error: ${error.message}`;
+        }
+      }
       Notify.Error({
-        msg: error instanceof Error
-          ? error.message
-          : "Please grant microphone permission to record audio.",
+        msg: errorMessage,
       });

107-120: Add TypeScript return types to control functions.

The control functions lack explicit return type annotations. Adding them would improve type safety and documentation.

-  const startRecording = () => {
+  const startRecording = (): void => {
     setIsRecording(true);
   };

-  const stopRecording = () => {
+  const stopRecording = (): void => {
     setIsRecording(false);
     setWaveform([]);
   };

-  const resetRecording = () => {
+  const resetRecording = (): void => {
     setAudioURL("");
     setBlob(null);
     setWaveform([]);
   };

122-131: Add explicit return type interface.

Define an interface for the hook's return value to improve type safety and documentation.

+interface VoiceRecorderHook {
+  audioURL: string;
+  isRecording: boolean;
+  startRecording: () => void;
+  stopRecording: () => void;
+  blob: Blob | null;
+  waveform: number[];
+  resetRecording: () => void;
+}

-const useVoiceRecorder = (handleMicPermission: (allowed: boolean) => void) => {
+const useVoiceRecorder = (handleMicPermission: (allowed: boolean) => void): VoiceRecorderHook => {

133-157: Add comprehensive JSDoc documentation.

The requestRecorder function would benefit from detailed JSDoc documentation explaining its purpose, parameters, return value, and possible errors.

+/**
+ * Requests access to the user's microphone and creates a MediaRecorder instance.
+ * Includes special handling for iOS Safari compatibility.
+ * 
+ * @throws {Error} When microphone access is denied or initialization fails
+ * @returns {Promise<MediaRecorder>} A configured MediaRecorder instance
+ */
 async function requestRecorder() {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 228856c and 394cd67.

📒 Files selected for processing (2)
  • src/CAREUI/interactive/KeyboardShortcut.tsx (2 hunks)
  • src/Utils/useVoiceRecorder.ts (1 hunks)
🔇 Additional comments (2)
src/CAREUI/interactive/KeyboardShortcut.tsx (2)

1-1: LGTM! Import changes are well-structured.

The import changes follow best practices:

  • Using Fragment from 'react/jsx-runtime' is optimal for performance
  • Relative import path for utils improves maintainability

Also applies to: 4-4


75-78: LGTM! Well-structured component with clear props interface.

The component has a clear single responsibility and good TypeScript typing.

src/Utils/useVoiceRecorder.ts Show resolved Hide resolved
@shivankacker
Copy link
Member Author

@nihal467 resolved merge conflicts, deploy preview failing due to cache issue, nothing else.

@shivankacker shivankacker removed the Deploy-Failed Deplyment is not showing preview label Nov 7, 2024
Copy link

github-actions bot commented Nov 9, 2024

👋 Hi, @shivankacker,
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.

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

image

@shivankacker the file upload is still not working

@nihal467
Copy link
Member

nihal467 commented Nov 13, 2024

Enhancement

image

  • the users never knew that its a clickable tooltip
  • if we reject all auto-fill, the notification shouldn't say "autofill completed"

image

  • when we talk about oral care in nursing, its filling disabled field in oral issues

image

  • the above two section are not auto-filling in scribe

@github-actions github-actions bot removed the merge conflict pull requests with merge conflict label Nov 13, 2024
@shivankacker
Copy link
Member Author

shivankacker commented Nov 13, 2024

@nihal467 enhancements can be taken up later, they will also be dependent on the plugin (no changes in care). I have added an ignore rule for oral issue.

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 (6)
src/components/Form/FormFields/Autocomplete.tsx (2)

187-191: Well-implemented ARIA attributes for enhanced accessibility.

The addition of data-cui-listbox attributes improves accessibility and provides better integration with assistive technologies. The structured data format allows for better state management and value injection.

Consider documenting these attributes in your component's API documentation to help other developers understand their purpose and usage.


117-117: Well-structured implementation of value injection pattern.

The implementation effectively combines React refs, custom hooks, and ARIA attributes to create a robust value injection system. This aligns well with the PR's objective of making Scribe aware of existing form data.

A few architectural considerations:

  1. The pattern could be abstracted into a higher-order component for reuse across other form components
  2. Consider adding error boundaries to handle potential JSON parsing errors
  3. Document the value injection pattern in your architecture documentation

Would you like help creating a higher-order component to abstract this pattern?

Also applies to: 168-176, 187-191

src/components/Patient/DailyRounds.tsx (3)

Line range hint 826-861: Consider extracting nursing care form handling

The nursing care form handling logic could be extracted into a custom hook to improve maintainability and reusability.

+// useNursingCareForm.ts
+const useNursingCareForm = (initialNursing: any) => {
+  const handleNursingChange = useCallback((log: any) => ({
+    name: "nursing",
+    value: log.nursing,
+  }), []);
+  
+  return { handleNursingChange };
+};

 // In component
-<NursingCare
-  log={{ nursing: state.form.nursing }}
-  onChange={(log) =>
-    handleFormFieldChange({
-      name: "nursing",
-      value: log.nursing,
-    })
-  }
+const { handleNursingChange } = useNursingCareForm(state.form.nursing);
+<NursingCare
+  log={{ nursing: state.form.nursing }}
+  onChange={(log) => handleFormFieldChange(handleNursingChange(log))}
 />

869-872: Consider extracting doctor's log section

The doctor's log section contains complex UI and logic. Consider extracting it into a separate component to improve maintainability.

+// DoctorsLogSection.tsx
+interface DoctorsLogSectionProps {
+  diagnoses: ConsultationDiagnosis[];
+  diagnosisSuggestions: ICD11DiagnosisModel[];
+  investigations: any[];
+  showDiscontinuedPrescriptions: boolean;
+  onDiagnosisUpdate: () => void;
+  onInvestigationsChange: (investigations: any[]) => void;
+  onDiscontinuedPrescriptionsChange: (show: boolean) => void;
+}
+
+const DoctorsLogSection: React.FC<DoctorsLogSectionProps> = ({
+  diagnoses,
+  diagnosisSuggestions,
+  investigations,
+  showDiscontinuedPrescriptions,
+  onDiagnosisUpdate,
+  onInvestigationsChange,
+  onDiscontinuedPrescriptionsChange,
+}) => {
+  return (
+    <div className="flex flex-col gap-10 divide-y-2 divide-dashed divide-secondary-600 border-t-2 border-dashed border-secondary-600 pt-6">
+      {/* Existing doctor's log content */}
+    </div>
+  );
+};
🧰 Tools
🪛 Biome

[error] 869-951: 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)


Line range hint 712-737: Remove unnecessary fragment

The fragment wrapping the blood sugar level field is unnecessary as it contains only one child element.

-<>
  <TextFormField
    {...field("blood_sugar_level")}
    labelSuffix="mg/dL"
    min={0}
    max={700}
    type="number"
    thresholds={[
      {
        value: 0,
        className: "text-danger-500",
        label: "Low",
      },
      {
        value: 69,
        className: "text-primary-500",
        label: "Normal",
      },
      {
        value: 110,
        className: "text-danger-500",
        label: "High",
      },
    ]}
  />
-</>
public/locale/en.json (1)

506-507: Consider improving clarity and consistency of user feedback messages.

Some suggestions to enhance user experience:

  • "Copilot is thinking..." could be more specific, e.g., "Processing your voice input..."
  • "We are hearing you..." could be more formal, e.g., "Processing audio input..."
  • Consider adding an ellipsis (...) to "Reviewing field" for consistency with other loading states
  • Consider making "This is what we heard" more formal, e.g., "Transcribed audio content"

Also applies to: 730-730, 1129-1130, 1229-1230

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 394cd67 and c13d3d7.

📒 Files selected for processing (6)
  • public/locale/en.json (12 hunks)
  • src/Routers/AppRouter.tsx (1 hunks)
  • src/Utils/request/api.tsx (0 hunks)
  • src/components/Form/FormFields/Autocomplete.tsx (4 hunks)
  • src/components/Patient/DailyRounds.tsx (12 hunks)
  • src/pluginTypes.ts (2 hunks)
💤 Files with no reviewable changes (1)
  • src/Utils/request/api.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/Routers/AppRouter.tsx
  • src/pluginTypes.ts
🧰 Additional context used
🪛 Biome
src/components/Patient/DailyRounds.tsx

[error] 712-737: 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 (4)
src/components/Form/FormFields/Autocomplete.tsx (1)

173-176: 🛠️ Refactor suggestion

Prevent potential infinite update loops in useEffect.

The current implementation might cause infinite loops if the parent component updates its state in response to the onChange callback. Consider adding additional checks or debouncing the updates.

Consider this implementation to prevent potential loops:

  useEffect(() => {
-   if (props.value !== domValue && typeof domValue !== "undefined")
+   if (props.value !== domValue && 
+       typeof domValue !== "undefined" && 
+       typeof props.value !== "undefined") {
      props.onChange(domValue);
+   }
  }, [domValue]);
src/components/Patient/DailyRounds.tsx (2)

683-688: Improved input validation with TextFormField

The replacement of range fields with TextFormField components includes proper validation constraints:

  • Pulse: 0-200 bpm
  • Respiratory rate: 0-150 bpm
  • SpO2: 0-100%

The implementation includes appropriate min/max values and units.

Also applies to: 744-749, 769-774


658-663: Well-implemented conditional form field visibility

Good implementation of the oral issue field's visibility and state management:

  • Field is disabled when nutrition route is not "ORAL"
  • Form state is properly cleared when nutrition route changes
  • Scribe integration is conditionally disabled
public/locale/en.json (1)

265-266: LGTM! The new translations align with the Scribe migration objectives.

The added translations appropriately support the voice recording, transcription, and auto-filling features being migrated.

Also applies to: 347-347, 506-507, 730-730, 1078-1078, 1108-1108, 1129-1130, 1195-1195, 1199-1199, 1216-1216, 1229-1230, 1320-1320

src/components/Patient/DailyRounds.tsx Show resolved Hide resolved
@nihal467
Copy link
Member

nihal467 commented Nov 13, 2024

conditional approved it, @shivankacker take up enhancement as separate issue

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 (3)
src/components/Patient/DailyRounds.tsx (3)

561-565: Consider enhancing Scribe integration with additional context attributes.

The Scribe integration looks good, but consider adding data attributes to provide more context about the form's purpose and structure:

 <form
   className="w-full max-w-4xl rounded-lg bg-white px-3 py-5 shadow sm:px-6 md:py-11"
   data-scribe-form
+  data-scribe-form-type="daily-rounds"
+  data-scribe-patient-id={patientId}
+  data-scribe-consultation-id={consultationId}
 >

856-859: Simplify onChange handler using object shorthand.

The onChange handler can be simplified:

-onChange={(log) =>
-  handleFormFieldChange({
-    name: "nursing",
-    value: log.nursing,
-  })
-}
+onChange={(log) => handleFormFieldChange({ name: "nursing", value: log.nursing })}

Line range hint 267-341: Consider extracting form validation logic into a custom hook.

The validation logic is complex and could be reused across similar forms. Consider extracting it into a custom hook:

// useDailyRoundsValidation.ts
export const useDailyRoundsValidation = (form: DailyRoundsModel, t: TFunction) => {
  return useCallback(() => {
    const errors = { ...initError };
    let invalidForm = false;
    
    // ... existing validation logic ...
    
    return { errors, isValid: !invalidForm };
  }, [form, t]);
};

This would improve maintainability and allow reuse in similar medical forms.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between c13d3d7 and 01bf5af.

📒 Files selected for processing (1)
  • src/components/Patient/DailyRounds.tsx (11 hunks)
🧰 Additional context used
🪛 Biome
src/components/Patient/DailyRounds.tsx

[error] 710-735: 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 (1)
src/components/Patient/DailyRounds.tsx (1)

681-686: Verify vital signs ranges against medical standards.

The implementation of vital signs validation looks good, but please verify these ranges with medical professionals:

  • Pulse: 0-200 bpm
  • Respiratory rate: 0-150 bpm
  • SpO2: 0-100%

Also applies to: 742-747, 767-772

✅ Verification successful

Vital signs ranges appear to be consistent with medical standards

Based on the codebase analysis, the vital signs ranges are already implemented consistently across different components and align with typical medical standards:

  • Pulse (0-200 bpm): Found in both DailyRounds.tsx and Vitals.tsx
  • Respiratory rate (0-150 bpm): Consistent in DailyRounds.tsx and Vitals.tsx
  • SpO2 (0-100%): Correctly bounded between 0-100% in multiple components

The ranges are also used in conjunction with thresholds for medical interpretation, suggesting they've been previously validated. The implementation shows careful consideration of medical parameters across the application.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other vital signs validation in the codebase
rg -A 2 "min={[0-9].*}.*max={[0-9].*}" --type tsx

Length of output: 167


Script:

#!/bin/bash
# Search for vital signs validation patterns with proper regex escaping
rg -A 2 'min=\{[0-9]+\}.*max=\{[0-9]+\}' --type tsx

# Alternative search for min/max attributes
rg -A 2 '(min|max)="\d+"|min={\d+}|max={\d+}' --type tsx

# Search for specific vital signs related fields
rg -B 2 -A 2 '(pulse|respiratory|spo2|SpO2|oxygen).*type="number"' --type tsx

Length of output: 387


Script:

#!/bin/bash
# Search for vital signs validation patterns without file type restriction
rg -A 2 'min=\{[0-9]' 'src/'

# Search for specific vital signs related fields
rg -B 2 -A 2 '(pulse|respiratory|spo2|SpO2|oxygen).*type=' 'src/'

# Search for any TextFormField with min/max props
rg -B 2 -A 2 'TextFormField.*min.*max' 'src/'

Length of output: 12692

@khavinshankar khavinshankar merged commit 5bb46fa into develop Nov 13, 2024
58 checks passed
@khavinshankar khavinshankar deleted the scribe-context branch November 13, 2024 10:30
Copy link

@shivankacker @shivankacker 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants