From e2abfa6ed085ee9b5b3489e893ea58a0c5af3cee Mon Sep 17 00:00:00 2001 From: SwanandBhuskute Date: Thu, 21 Nov 2024 15:06:21 +0000 Subject: [PATCH] updates on comments, moving debounce and nested code to proper files --- src/Utils/.Notifications.js.swp | Bin 12288 -> 0 bytes src/Utils/Notifications.js | 2 +- src/Utils/utils.ts | 52 +++++++++++------- .../Investigations/ShowInvestigation.tsx | 26 +-------- src/components/Patient/DiagnosesFilter.tsx | 6 +- src/components/Patient/PatientRegister.tsx | 4 +- src/hooks/useDebounce.ts | 22 ++++++++ 7 files changed, 62 insertions(+), 50 deletions(-) delete mode 100644 src/Utils/.Notifications.js.swp create mode 100644 src/hooks/useDebounce.ts diff --git a/src/Utils/.Notifications.js.swp b/src/Utils/.Notifications.js.swp deleted file mode 100644 index 322de92b8df7c12f11eab96aae18725ad1837f91..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI2ON<#U(`PPU+u#xU=^?mSOu&CRspMkRlq7>6|f3e1*`&Af&ZZbyvEp}`xv{v5y|8K z|MP$UUwxFZ%itaG5;zGaK^bfY4E*{CV>iH8;4|;_xG<6sN8`2b_rz{lVt@FBPed~gUH1P8!Quo3)nKVv_GpTKqS z0k{m_1{XmS%z>xD@6h;1@GbZnXwAO__G1;W3RnfK0#<>$QK0uMBkBR7NWW6onU^w_ z1tDcJW~NAliJ-1op+{Xmmh;?e6!e-{j?v8CwU!t)wt-KDSt)tP4HENA-HySVIM<4$ zA`dU`DSDpQj*8dY0>92sp-Vap^^E5(D~*rS?s8c#qI^|@N3~E$8ZR+sHjt)XXeRX{ zIr@ty9HcN3L1HS-0PVjs#8-W39k#fy?e9mb>8Q-7`JwxPW?OQN!#;~#X9%Z zbo|x<^2s}ds4DKQxLz11qOevRGddfFBd=BJXhWwkr!9$xA&ssYUwaHjp#^gmeX;T) zOG}OP8OIW9Xy*($uSAZnHT}uwM^~KL(OnUpMcx!WniwvHGkv?^I@OMb1B{yQ=$_?a zTlCi2>T*?`mWX{a3utBrxg|=XHXL2F+O7WF&UHHqbS1kQL0g={U@_h8X~Mn_FD(mCxgx@*MUr)R8l*QYa9@F$R1CK!6c0k3ZnjQmY*uAc zgG{%XVLE?4GYv&lR}I=rlj!n&+I=a;R z@X_f|Y0xwYz43uHIjFt#9!hVK`Mi_OnymiQYo=$ewd|(MUOpZ))S7WA{KOTZXu7;s zn?H-a910R8A|VTohvHa4LFDZP*)rEP5%Nxjc9qNJA~r_)D7}?RcEy?&PRD!cLoa|Y zAuHr_+|>D~Y3R|xrM6PIZ!1|P-^#8T*F=S!FsL__lgICbI1G#~Nj7VIZ-97k@pZfcdsF_x%Opbe76}lse>wCsHF{XXRjUugf(m-q#w@l0?Kc}yuwiI)` zorvTF50F8B=a{Z4$(5)>L#T`kD>pmb5)pLOiD8#K9J2BQnW$ErOjT%VS}({4Ci8(> zATjBL!cS$vcg#7pcr}9mp^bLT31LH~k@eAGudF6~-VW75Tx*B=Za{+{F?VQZAzlhX zQKYUue-<>&U&Su { .replace(/^[A-Z]/, (c) => c.toLowerCase()); }; -export const useDebounce = ( - callback: (...args: string[]) => void, - delay: number, -) => { - const callbackRef = useRef(callback); - useEffect(() => { - callbackRef.current = callback; - }, [callback]); - - const timeoutRef = useRef | null>(null); - const debouncedCallback = (...args: string[]) => { - if (timeoutRef.current) { - clearTimeout(timeoutRef.current); +export function setNestedValueSafely( + obj: Record, + path: string, + value: any, +) { + const keys = path.split("."); + let current = obj; + + for (let i = 0; i < keys.length - 1; i++) { + const key = keys[i]; + + // Protect against prototype pollution by skipping unsafe keys + if (key === "__proto__" || key === "constructor" || key === "prototype") { + continue; } - timeoutRef.current = setTimeout(() => { - callbackRef.current(...args); - }, delay); - }; - return debouncedCallback; -}; + + // Use Object.create(null) to prevent accidental inheritance from Object prototype + current[key] = current[key] || Object.create(null); + current = current[key]; + } + + const lastKey = keys[keys.length - 1]; + + // Final key assignment, ensuring no prototype pollution vulnerability + if ( + lastKey !== "__proto__" && + lastKey !== "constructor" && + lastKey !== "prototype" + ) { + current[lastKey] = value; + } +} diff --git a/src/components/Facility/Investigations/ShowInvestigation.tsx b/src/components/Facility/Investigations/ShowInvestigation.tsx index 0e298377002..15c676220fd 100644 --- a/src/components/Facility/Investigations/ShowInvestigation.tsx +++ b/src/components/Facility/Investigations/ShowInvestigation.tsx @@ -9,6 +9,7 @@ import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; import useQuery from "@/Utils/request/useQuery"; +import { setNestedValueSafely } from "@/Utils/utils"; const initialState = { changedFields: {}, @@ -91,31 +92,8 @@ export default function ShowInvestigation(props: ShowInvestigationProps) { const handleValueChange = (value: any, name: string) => { const changedFields = { ...state.changedFields }; - const keys = name.split("."); - let current = changedFields; - for (let i = 0; i < keys.length - 1; i++) { - const key = keys[i]; - - // Protect against prototype pollution by skipping unsafe keys - crai - if (key === "__proto__" || key === "constructor" || key === "prototype") { - continue; - } - - // Use Object.create(null) to prevent accidental inheritance from Object prototype - coderabbit - current[key] = current[key] || Object.create(null); - current = current[key]; - } - const lastKey = keys[keys.length - 1]; - - // Final key assignment, ensuring no prototype pollution vulnerability - coderabbit - if ( - lastKey !== "__proto__" && - lastKey !== "constructor" && - lastKey !== "prototype" - ) { - current[lastKey] = value; - } + setNestedValueSafely(changedFields, name, value); dispatch({ type: "set_changed_fields", changedFields }); }; diff --git a/src/components/Patient/DiagnosesFilter.tsx b/src/components/Patient/DiagnosesFilter.tsx index 31cbce47d7e..e0d8c543ce9 100644 --- a/src/components/Patient/DiagnosesFilter.tsx +++ b/src/components/Patient/DiagnosesFilter.tsx @@ -5,10 +5,12 @@ import { ICD11DiagnosisModel } from "@/components/Diagnosis/types"; import { getDiagnosesByIds } from "@/components/Diagnosis/utils"; import AutocompleteMultiSelectFormField from "@/components/Form/FormFields/AutocompleteMultiselect"; +import useDebounce from "@/hooks/useDebounce"; + import { Error } from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import useQuery from "@/Utils/request/useQuery"; -import { mergeQueryOptions, useDebounce } from "@/Utils/utils"; +import { mergeQueryOptions } from "@/Utils/utils"; export const FILTER_BY_DIAGNOSES_KEYS = [ "diagnoses", @@ -70,7 +72,7 @@ export default function DiagnosesFilter(props: Props) { const debouncedQuery = useDebounce((query: string) => { refetch({ query: { query } }); - }, 0); + }, 300); return ( { } } } - }, 0); + }, 300); const handleDialogClose = (action: string) => { if (action === "transfer") { diff --git a/src/hooks/useDebounce.ts b/src/hooks/useDebounce.ts new file mode 100644 index 00000000000..961a976d893 --- /dev/null +++ b/src/hooks/useDebounce.ts @@ -0,0 +1,22 @@ +import { useEffect, useRef } from "react"; + +export default function useDebounce( + callback: (...args: string[]) => void, + delay: number, +) { + const callbackRef = useRef(callback); + useEffect(() => { + callbackRef.current = callback; + }, [callback]); + + const timeoutRef = useRef | null>(null); + const debouncedCallback = (...args: string[]) => { + if (timeoutRef.current) { + clearTimeout(timeoutRef.current); + } + timeoutRef.current = setTimeout(() => { + callbackRef.current(...args); + }, delay); + }; + return debouncedCallback; +}