Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions public/locale/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -3466,6 +3466,7 @@
"medicine_administration": "Medicine Administration",
"medicine_administration_history": "Medicine Administration History",
"medicine_dispensed": "Medicine Dispensed",
"medicine_instructions": "Medicine Instructions",
"medicine_prescription": "Medicine Prescription",
"medicines": "Medicines",
"medicines_administered": "Medicine(s) administered",
Expand Down Expand Up @@ -4008,6 +4009,7 @@
"now": "now",
"now_serving": "Now Serving",
"now_using_the_latest_version_of_care": "Now using the latest version of CARE",
"num": "#",
Comment thread
abhimanyurajeesh marked this conversation as resolved.
Outdated
"number_min_error": "Must be at least {{min}}",
"number_of_aged_dependents": "Number of Aged Dependents (Above 60)",
"number_of_beds": "Number of beds",
Expand Down Expand Up @@ -4261,6 +4263,7 @@
"patient_identifiers": "Patient Identifiers",
"patient_information": "Patient Information",
"patient_instruction": "Patient Instruction",
"patient_ip_location": "Patient IP Location",
"patient_is_deceased": "Patient is deceased",
"patient_location": "Patient Location",
"patient_login": "Log in as Patient",
Expand Down Expand Up @@ -6646,6 +6649,7 @@
"workflow_progress": "Workflow Progress",
"working_status": "Working Status",
"x": "X",
"x_of_y": "{{current}} of {{total}}",
"year": "Year",
"year_of_birth": "Year of Birth",
"year_of_birth_format": "Year of birth must be in YYYY format",
Expand Down
5 changes: 5 additions & 0 deletions src/CAREUI/misc/PrintPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type Props = {
facility?: FacilityRead;
templateSlug: string;
hideFacilityHeader?: boolean;
footer?: ReactNode;
};

export default function PrintPreview(props: Props) {
Expand Down Expand Up @@ -103,6 +104,7 @@ export default function PrintPreview(props: Props) {
facility={props.facility}
templateSlug={props.templateSlug}
hideFacilityHeader={props.hideFacilityHeader}
footer={props.footer}
>
{props.children}
</FacilityPrintLayout>
Expand Down Expand Up @@ -312,11 +314,13 @@ function FacilityPrintLayout({
facility,
children,
hideFacilityHeader,
footer,
}: {
templateSlug?: string;
facility?: FacilityRead;
children: ReactNode;
hideFacilityHeader?: boolean;
footer?: ReactNode;
}) {
if (!facility) {
return <>{children}</>;
Expand Down Expand Up @@ -383,6 +387,7 @@ function FacilityPrintLayout({
/>
Comment thread
abhimanyurajeesh marked this conversation as resolved.
</div>
)}
{footer && <div>{footer}</div>}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
</div>
);
}
64 changes: 49 additions & 15 deletions src/components/Common/PrintTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ interface GenericTableProps {
headers: HeaderRow[];
rows: TableRowType[] | undefined;
className?: string;
classNameCell?: string;
cellClassName?: string;
headerClassName?: string;
tableClassName?: string;
cellConfig?: Record<string, CellConfig>;
renderCell?: (
key: string,
Expand All @@ -42,13 +44,33 @@ export default function PrintTable({
headers,
rows,
className,
classNameCell,
cellClassName,
headerClassName,
tableClassName,
cellConfig,
renderCell,
rowClassName,
}: GenericTableProps) {
const { t } = useTranslation();

// Pre-compute which cells are covered by a rowspan from a previous row.
// Rows can encode `_span_${key}: "N"` to span N rows for that column.
const skipCells: Record<string, Set<number>> = {};
headers.forEach(({ key }) => {
skipCells[key] = new Set();
});
rows?.forEach((row, rowIndex) => {
headers.forEach(({ key }) => {
const spanVal = row[`_span_${key}`];
if (spanVal) {
const span = parseInt(spanVal);
for (let i = 1; i < span; i++) {
skipCells[key].add(rowIndex + i);
}
}
});
});
Comment thread
abhimanyurajeesh marked this conversation as resolved.

const getCellContent = (
key: string,
value: string | undefined,
Expand All @@ -66,7 +88,12 @@ export default function PrintTable({
};

return (
<div className="overflow-hidden rounded border border-gray-200">
<div
className={cn(
"overflow-hidden rounded border border-gray-200",
tableClassName,
)}
>
<Table className="w-full">
<TableHeader>
<TableRow className="bg-transparent hover:bg-transparent divide-x divide-gray-200 border-b-gray-200">
Expand All @@ -76,6 +103,7 @@ export default function PrintTable({
index == 0 && "first:rounded-l-md",
"h-auto py-1 pl-2 pr-2 text-black text-center ",
width && `w-${width}`,
headerClassName,
)}
key={key}
>
Expand All @@ -95,18 +123,24 @@ export default function PrintTable({
rowClassName?.(row, index),
)}
>
{headers.map(({ key }) => (
<TableCell
className={cn(
"wrap-break-words whitespace-normal text-center",
classNameCell,
cellConfig?.[key]?.className,
)}
key={key}
>
{getCellContent(key, row[key], index)}
</TableCell>
))}
{headers.map(({ key }) => {
if (skipCells[key]?.has(index)) return null;
const spanVal = row[`_span_${key}`];
const rowSpan = spanVal ? parseInt(spanVal) : undefined;
return (
<TableCell
rowSpan={rowSpan}
className={cn(
"wrap-break-words whitespace-normal text-center",
Comment thread
abhimanyurajeesh marked this conversation as resolved.
Outdated
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
cellClassName,
cellConfig?.[key]?.className,
)}
key={key}
>
{getCellContent(key, row[key], index)}
</TableCell>
);
})}
</TableRow>
))}
</TableBody>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Medicine/FormattedDosage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export function FormattedDosage({
return (
<span
className={cn(
"rounded bg-yellow-100 px-1.5 py-0.5 font-semibold text-yellow-900",
"rounded bg-yellow-100 px-1.5 -mx-1.5 py-0.5 font-semibold text-yellow-900",
className,
)}
>
Expand Down
26 changes: 20 additions & 6 deletions src/components/Medicine/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,30 @@ import {
MedicationRequestDosageInstruction,
} from "@/types/emr/medicationRequest/medicationRequest";
import { round } from "@/Utils/decimal";
import Decimal from "decimal.js";
Comment thread
abhimanyurajeesh marked this conversation as resolved.

Comment thread
abhimanyurajeesh marked this conversation as resolved.
/**
* Round to accounting precision for dosage/medication display.
* If the fractional part is all zeros (e.g. "5.00"), the decimal portion is omitted.
*/
export function roundDosage(value: string | number | Decimal): string {
const fixed = round(value);
const [intPart, fracPart] = fixed.split(".");
if (fracPart && /^0+$/.test(fracPart)) {
return intPart;
}
return fixed;
}

// Helper function to format dosage in Rx style
export function formatDosage(instruction?: MedicationRequestDosageInstruction) {
if (!instruction?.dose_and_rate) return "";

const { dose_range, dose_quantity } = instruction.dose_and_rate;
if (dose_range) {
return `${round(dose_range.low.value)} ${dose_range.low.unit.display} -> ${round(dose_range.high.value)} ${dose_range.high.unit.display}`;
return `${roundDosage(dose_range.low.value)} ${dose_range.low.unit.display} -> ${roundDosage(dose_range.high.value)} ${dose_range.high.unit.display}`;
} else if (dose_quantity) {
return `${round(dose_quantity.value)} ${dose_quantity.unit.display}`;
return `${roundDosage(dose_quantity.value)} ${dose_quantity.unit.display}`;
}
return "";
}
Expand All @@ -34,7 +48,7 @@ export function isNonUnitDose(
const { dose_range, dose_quantity } = doseAndRate;
if (dose_range) return true;
if (dose_quantity?.value == null) return false;
return round(dose_quantity.value) !== round(1);
return roundDosage(dose_quantity.value) !== roundDosage(1);
}

// Helper function to format dosage instructions in Rx style
Expand Down Expand Up @@ -62,7 +76,7 @@ export function formatSig(instruction?: MedicationRequestDosageInstruction) {

export function formatDoseRange(range?: DoseRange): string {
if (!range?.high?.value) return "";
return `${round(range.low.value)} → ${round(range.high?.value)} ${range.high?.unit?.display}`;
return `${roundDosage(range.low.value)} → ${roundDosage(range.high?.value)} ${range.high?.unit?.display}`;
}

/**
Expand Down Expand Up @@ -140,7 +154,7 @@ export function formatTotalUnits(
const dose = prnInstruction.dose_and_rate?.dose_quantity?.value;
const doseUnit =
prnInstruction.dose_and_rate?.dose_quantity?.unit?.display || unitText;
return dose ? `${round(dose)} ${doseUnit} (PRN)` : "PRN";
return dose ? `${roundDosage(dose)} ${doseUnit} (PRN)` : "PRN";
}

// Sum total dose across all instructions
Expand Down Expand Up @@ -168,5 +182,5 @@ export function formatTotalUnits(

if (!hasAnyDose) return "";

return `${round(String(totalValue))} ${doseUnit}${hasTapered ? " (tapered)" : ""}`;
return `${roundDosage(String(totalValue))} ${doseUnit}${hasTapered ? " (tapered)" : ""}`;
}
Loading
Loading