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

Basic CRUD pages for Devices #10560

Open
wants to merge 14 commits into
base: develop
Choose a base branch
from
103 changes: 101 additions & 2 deletions public/locale/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,9 @@
"add_beds_to_configure_presets": "Add beds to this location to configure presets for them.",
"add_consultation": "Add consultation",
"add_consultation_update": "Add Consultation Update",
"add_contact_point": "Add Contact Point",
"add_details_of_patient": "Add Details of Patient",
"add_device": "Add Device",
"add_exception": "Add Exception",
"add_facility": "Add Facility",
"add_files": "Add Files",
Expand Down Expand Up @@ -415,6 +417,10 @@
"assigned_facility": "Facility assigned",
"assigned_to": "Assigned to",
"assigned_volunteer": "Assigned Volunteer",
"associate": "Associate",
"associate_location": "Associate Location",
"associate_location_description": "Select a location to associate with this device",
"associating": "Associating...",
"at_time": "at <strong>{{time}}</strong>",
"atypical_presentation_details": "Atypical presentation details",
"audio__allow_permission": "Please allow microphone permission in site settings",
Expand All @@ -437,6 +443,7 @@
"auto_generated_for_care": "Auto Generated for Care",
"autofilled_fields": "Autofilled Fields",
"availabilities": "Availabilities",
"availability_status": "Availability Status",
"available_features": "Available Features",
"available_in": "Available in",
"available_time_slots": "Available Time Slots",
Expand Down Expand Up @@ -507,9 +514,11 @@
"category_description": "Choose the category that best describes the resource needed.",
"caution": "Caution",
"central_nursing_station": "Central Nursing Station",
"change": "Change",
"change_avatar": "Change Avatar",
"change_avatar_note": "JPG, GIF or PNG. 1MB max.",
"change_file": "Change File",
"change_location": "Change Location",
"change_phone_number": "Change Phone Number",
"change_status": "Change Status",
"chat_on_whatsapp": "Chat on Whatsapp",
Expand Down Expand Up @@ -614,6 +623,26 @@
"contact_person_number": "Contact person number",
"contact_phone": "Contact Person Number",
"contact_phone_description": "Phone number to reach the contact person.",
"contact_point_placeholder__email": "Enter email address",
"contact_point_placeholder__fax": "Enter fax number",
"contact_point_placeholder__other": "Enter contact value",
"contact_point_placeholder__pager": "Enter pager number",
"contact_point_placeholder__phone": "Enter phone number",
"contact_point_placeholder__sms": "Enter SMS number",
"contact_point_placeholder__url": "Enter URL",
"contact_points": "Contact Points",
"contact_system_email": "Email",
"contact_system_fax": "Fax",
"contact_system_other": "Other",
"contact_system_pager": "Pager",
"contact_system_phone": "Phone",
"contact_system_sms": "SMS",
"contact_system_url": "URL",
"contact_use_home": "Home",
"contact_use_mobile": "Mobile",
"contact_use_old": "Old",
"contact_use_temp": "Temporary",
"contact_use_work": "Work",
"contact_with_confirmed_carrier": "Contact with confirmed carrier",
"contact_with_suspected_carrier": "Contact with suspected carrier",
"contact_your_admin_to_add_facilities": "Contact your admin to add facilities",
Expand Down Expand Up @@ -663,6 +692,7 @@
"criticality": "Criticality",
"csv_file_in_the_specified_format": "Select a CSV file in the specified format",
"current_address": "Current Address",
"current_location_description": "The current location of this device",
"current_organizations": "Current Organizations",
"current_password": "Current Password",
"current_role": "Current Role",
Expand All @@ -688,12 +718,15 @@
"date_of_return": "Date of Return",
"date_of_test": "Date of sample collection for Covid testing",
"date_range": "Date Range",
"dates_and_identifiers": "Dates & Identifiers",
"day": "Day",
"death_report": "Death Report",
"delete": "Delete",
"delete_account": "Delete account",
"delete_account_btn": "Yes, delete this account",
"delete_account_note": "Deleting this account will remove all associated data and cannot be undone.",
"delete_device": "Delete Device",
"delete_device_confirmation": "Are you sure you want to delete this device? This action cannot be undone.",
"delete_facility": "Delete Facility",
"delete_item": "Delete {{name}}",
"delete_record": "Delete Record",
Expand All @@ -710,6 +743,17 @@
"details_of_origin_facility": "Details of origin facility",
"details_of_patient": "Details of patient",
"details_of_shifting_approving_facility": "Details of shifting approving facility",
"device_availability_status_available": "Available",
"device_availability_status_damaged": "Damaged",
"device_availability_status_destroyed": "Destroyed",
"device_availability_status_lost": "Lost",
"device_contact_description": "Contact points associated with this device",
"device_information": "Device Information",
"device_not_found": "Device not found",
"device_status_active": "Active",
"device_status_entered_in_error": "Entered in Error",
"device_status_inactive": "Inactive",
"devices": "Devices",
"diagnoses": "Diagnoses",
"diagnosis": "Diagnosis",
"diagnosis__confirmed": "Confirmed",
Expand Down Expand Up @@ -785,6 +829,8 @@
"edit_avatar_permission_error": "You do not have permissions to edit the avatar of this user",
"edit_caution_note": "A new prescription will be added to the consultation with the edited details and the current prescription will be discontinued.",
"edit_cover_photo": "Edit Cover Photo",
"edit_device": "Edit Device",
"edit_device_description": "Edit the details of the device",
"edit_facility": "Edit Facility",
"edit_history": "Edit History",
"edit_location": "Edit Location",
Expand Down Expand Up @@ -932,18 +978,27 @@
"end_time_before_start_error": "End time cannot be before start time",
"end_time_future_error": "End time cannot be in the future",
"ended": "Ended",
"enter_contact_value": "Enter contact value",
"enter_dosage_instructions": "Enter Dosage Instructions",
"enter_file_name": "Enter File Name",
"enter_identifier": "Enter device identifier",
"enter_lot_number": "Enter lot number",
"enter_manufacturer": "Enter manufacturer name",
"enter_message": "Start typing...",
"enter_mobile_number": "Enter Mobile Number",
"enter_mobile_otp": "Enter OTP sent to the given mobile number",
"enter_model_number": "Enter model number",
"enter_otp": "Enter OTP sent to the registered mobile with the respective ID",
"enter_part_number": "Enter part number",
"enter_phone_number": "Enter phone number",
"enter_phone_number_to_login_register": "Enter phone number to login/register",
"enter_registered_name": "Enter the registered name of the device",
"enter_serial_number": "Enter serial number",
"enter_tag_name": "Enter tag name",
"enter_tag_slug": "Enter tag slug",
"enter_the_file_name": "Enter the file name",
"enter_the_verification_code": "Enter the verification code sent to your phone",
"enter_user_friendly_name": "Enter a user friendly name for the device",
"enter_valid_age": "Please Enter Valid Age",
"enter_valid_dob": "Enter a valid date of birth",
"enter_valid_dob_age": "Please enter an age greater than 15 years",
Expand Down Expand Up @@ -976,8 +1031,10 @@
"exceptions": "Exceptions",
"expand_sidebar": "Expand Sidebar",
"expected_burn_rate": "Expected Burn Rate",
"expiration_date": "Expiration Date",
"expired": "Expired",
"expired_on": "Expired On",
"expires": "Expires",
"expires_on": "Expires On",
"export": "Export",
"export_live_patients": "Export Live Patients",
Expand Down Expand Up @@ -1115,6 +1172,7 @@
"i_declare": "I hereby declare that:",
"icd11_as_recommended": "As per ICD-11 recommended by WHO",
"icmr_specimen_referral_form": "ICMR Specimen Referral Form",
"identifier": "Identifier",
"immunisation-records": "Immunisation",
"in_consultation": "In-Consultation",
"in_progress": "In Progress",
Expand Down Expand Up @@ -1245,12 +1303,34 @@
"local_ip_address": "Local IP Address",
"local_ip_address_example": "e.g. 192.168.0.123",
"location": "Location",
"location_associated_successfully": "Location associated successfully",
"location_beds_empty": "No beds available in this location",
"location_created": "Location Created",
"location_description": "Location Description",
"location_details": "Location Details",
"location_form": "Location Form",
"location_form__area": "Area",
"location_form__bd": "Bed",
"location_form__bu": "Building",
"location_form__ca": "Cabinet",
"location_form__co": "Corridor",
"location_form__ho": "House",
"location_form__jdn": "Jurisdiction",
"location_form__lvl": "Level",
"location_form__rd": "Road",
"location_form__ro": "Room",
"location_form__si": "Site",
"location_form__ve": "Vehicle",
"location_form__vi": "Virtual",
"location_form__wa": "Ward",
"location_form__wi": "Wing",
"location_history": "Location History",
"location_management": "Location Management",
"location_name": "Location Name",
"location_status": "Location Status",
"location_status__active": "Active",
"location_status__inactive": "Inactive",
"location_status__unknown": "Unknown",
"location_updated": "Location Updated",
"location_updated_successfully": "Location updated successfully",
"locations": "Locations",
Expand All @@ -1264,6 +1344,7 @@
"logout": "Log Out",
"longitude": "Longitude",
"longitude_invalid": "Longitude must be between -180 and 180",
"lot_number": "Lot Number",
"low": "Low",
"lsg": "Lsg",
"make_facility_public": "Make this facility public",
Expand All @@ -1279,6 +1360,8 @@
"manage_tags": "Manage Tags",
"manage_tags_description": "Add or remove tags for this questionnaire",
"manage_user": "Manage User",
"manufacture_date": "Manufacture Date",
"manufactured": "Manufactured",
"manufacturer": "Manufacturer",
"map_acronym": "M.A.P.",
"mark_active": "Mark Active",
Expand Down Expand Up @@ -1335,6 +1418,7 @@
"mobile_otp_send_success": "OTP has been sent to the given mobile number.",
"mobile_otp_verify_error": "Failed to verify mobile number. Please try again later.",
"mobile_otp_verify_success": "Mobile number has been verified successfully.",
"model_number": "Model Number",
"moderate": "Moderate",
"modification_caution_note": "No modifications possible once added",
"modified": "Modified",
Expand Down Expand Up @@ -1389,6 +1473,8 @@
"no_country_found": "No country found",
"no_data_found": "No data found",
"no_departments_teams_found": "No Departments or Teams found",
"no_devices_available": "No devices available",
"no_devices_found": "No devices found",
"no_diagnoses_recorded": "No diagnoses recorded",
"no_doctors_found": "No Doctors Found",
"no_duplicate_facility": "You should not create duplicate facilities",
Expand All @@ -1402,6 +1488,8 @@
"no_investigation": "No investigation Reports found",
"no_investigation_suggestions": "No Investigation Suggestions",
"no_linked_facilities": "No Linked Facilities",
"no_location": "No location assigned",
"no_location_description": "This device is not currently assigned to any location",
"no_locations_available": "No locations available",
"no_locations_found": "No locations found",
"no_log_update_delta": "No changes since previous log update",
Expand Down Expand Up @@ -1527,6 +1615,7 @@
"page_not_found": "Page Not Found",
"pain": "Pain",
"pain_chart_description": "Mark region and intensity of pain",
"part_number": "Part Number",
"participants": "Participants",
"passport_number": "Passport Number",
"password": "Password",
Expand Down Expand Up @@ -1757,6 +1846,7 @@
"register_hospital": "Register Hospital",
"register_page_title": "Register As Hospital Administrator",
"register_patient": "Register Patient",
"registered_name": "Registered Name",
"reject": "Reject",
"rejected": "Rejected",
"relapse": "Relapse",
Expand Down Expand Up @@ -1898,13 +1988,14 @@
"search_by": "Search by",
"search_by_emergency_contact_phone_number": "Search by Emergency Contact Phone Number",
"search_by_emergency_phone_number": "Search by Emergency Phone Number",
"search_by_name": "Search by Name",
"search_by_name": "Search by name",
"search_by_patient_name": "Search by Patient Name",
"search_by_patient_no": "Search by Patient Number",
"search_by_phone_number": "Search by Phone Number",
"search_by_resource_title": "Search by resource title",
"search_by_username": "Search by username",
"search_country": "Search country...",
"search_devices": "Search Devices",
"search_encounters": "Search Encounters",
"search_for_allergies_to_add": "Search for allergies to add",
"search_for_diagnoses_to_add": "Search for diagnoses to add",
Expand All @@ -1929,8 +2020,11 @@
"select_additional_instructions": "Select additional instructions",
"select_admit_source": "Select Admit Source",
"select_all": "Select All",
"select_availability_status": "Select availability status",
"select_category": "Select a category",
"select_class": "Select Class",
"select_contact_system": "Select contact type",
"select_contact_use": "Select contact use",
"select_date": "Select date",
"select_department": "Select Department",
"select_diet_preference": "Select diet preference",
Expand Down Expand Up @@ -1968,7 +2062,7 @@
"select_seven_day_period": "Select a seven day period",
"select_site": "Select site",
"select_skills": "Select and add some skills",
"select_status": "Select Status",
"select_status": "Select status",
"select_sub_department": "Select sub-department",
"select_time": "Select time",
"select_time_slot": "Select time slot",
Expand Down Expand Up @@ -2093,6 +2187,7 @@
"symptom": "Symptom",
"symptoms": "Symptoms",
"symptoms_empty_message": "No symptoms recorded",
"system": "System",
"systolic": "Systolic",
"tachycardia": "Tachycardia",
"tag_name": "Tag Name",
Expand Down Expand Up @@ -2208,6 +2303,7 @@
"update_available": "Update Available",
"update_bed": "Update Bed",
"update_department": "Update Department",
"update_device": "Update Device",
"update_encounter": "Update Encounter",
"update_encounter_details": "Update Encounter Details",
"update_existing_facility": "Update the details of the existing facility.",
Expand Down Expand Up @@ -2245,6 +2341,7 @@
"upload_headings__supporting_info": "Upload Supporting Info",
"upload_report": "Upload Report",
"uploading": "Uploading",
"use": "Use",
"use_address_as_permanent": "Use this address for permanent address",
"use_phone_number_for_emergency": "Use this phone number for emergency contact",
"user_add_error": "Error while adding User",
Expand All @@ -2255,6 +2352,7 @@
"user_details": "User Details",
"user_details_update_error": "Error while updating user details",
"user_details_update_success": "User details updated successfully",
"user_friendly_name": "User Friendly Name",
"user_management": "User Management",
"user_not_available_for_appointments": "This user is not available for appointments",
"user_qualifications": "Qualifications",
Expand Down Expand Up @@ -2285,6 +2383,7 @@
"valid_otp_found": "Valid OTP found, Navigating to Appointments",
"valid_to": "Valid Till",
"valid_year_of_birth": "Please enter a valid year of birth (YYYY)",
"value": "Value",
"vehicle_preference": "Vehicle preference",
"vendor_name": "Vendor Name",
"ventilator_interface": "Respiratory Support Type",
Expand Down
22 changes: 21 additions & 1 deletion src/components/Location/LocationSearch.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useQuery } from "@tanstack/react-query";
import { useState } from "react";
import { useTranslation } from "react-i18next";

import {
Command,
Expand Down Expand Up @@ -33,6 +34,7 @@ export function LocationSearch({
disabled,
value,
}: LocationSearchProps) {
const { t } = useTranslation();
const [open, setOpen] = useState(false);
const [search, setSearch] = useState("");

Expand Down Expand Up @@ -61,6 +63,7 @@ export function LocationSearch({
<CommandInput
placeholder="Search locations..."
value={search}
className="outline-none border-none ring-0 shadow-none"
onValueChange={setSearch}
/>
<CommandEmpty>No locations found.</CommandEmpty>
Expand All @@ -74,7 +77,15 @@ export function LocationSearch({
setOpen(false);
}}
>
{location.name}
<span>{location.name}</span>
<span className="text-xs text-gray-500">
{t(`location_form__${location.form}`)}
{" in "}
{formatLocationParent(location)}
</span>
<span className="text-xs text-gray-500 ml-auto">
{t(`location_status__${location.status}`)}
</span>
Comment on lines +79 to +87
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Add error handling for missing translation keys.

The translation keys location_form__${location.form} and location_status__${location.status} might not exist in the translation files. Consider adding fallback values or error handling.

Run this script to check for missing translation keys:


🏁 Script executed:

#!/bin/bash
# Description: Check if all required translation keys exist in the English locale file.

# Get unique location forms and statuses from the codebase
forms=$(rg -o 'location_form__\w+' | sort -u)
statuses=$(rg -o 'location_status__\w+' | sort -u)

# Check if these keys exist in the English locale file
echo "Checking translation keys in locale file..."
for key in $forms $statuses; do
  if ! rg -q "\"$key\":" "public/locale/en.json"; then
    echo "Missing translation key: $key"
  fi
done

Length of output: 5415


Enhance Fallbacks for Missing Translations

The dynamic translation keys (location_form__${location.form} and location_status__${location.status}) currently lack a fallback mechanism. This may lead to unfriendly UI when a translation key is absent. Please implement fallbacks or leverage i18next’s default behavior to ensure a graceful display if the translation is missing. Also, note that the verification script appears to prepend file names to the keys, so double-check that the locale key extraction accurately reflects the keys used in the component.

</CommandItem>
))}
</CommandGroup>
Expand All @@ -83,3 +94,12 @@ export function LocationSearch({
</Popover>
);
}

const formatLocationParent = (location: LocationList) => {
const parents: string[] = [];
while (location.parent?.name) {
parents.push(location.parent?.name);
location = location.parent;
}
return parents.reverse().join(" > ");
};
Comment on lines +97 to +104
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add safeguard against infinite loops in formatLocationParent.

The while loop could potentially enter an infinite loop if there's a circular reference in the location hierarchy.

 const formatLocationParent = (location: LocationList) => {
   const parents: string[] = [];
+  const visited = new Set<string>();
   while (location.parent?.name) {
+    if (visited.has(location.parent.id)) {
+      console.error("Circular reference detected in location hierarchy");
+      break;
+    }
+    visited.add(location.parent.id);
     parents.push(location.parent?.name);
     location = location.parent;
   }
   return parents.reverse().join(" > ");
 };
📝 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 formatLocationParent = (location: LocationList) => {
const parents: string[] = [];
while (location.parent?.name) {
parents.push(location.parent?.name);
location = location.parent;
}
return parents.reverse().join(" > ");
};
const formatLocationParent = (location: LocationList) => {
const parents: string[] = [];
const visited = new Set<string>();
while (location.parent?.name) {
if (visited.has(location.parent.id)) {
console.error("Circular reference detected in location hierarchy");
break;
}
visited.add(location.parent.id);
parents.push(location.parent?.name);
location = location.parent;
}
return parents.reverse().join(" > ");
};

Loading
Loading