bugfix: Treatment detail auto-fill bug fixed.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import { Button } from '@/components/ui/shared/Button';
|
||||
import { Checkbox } from '@/components/ui/shared/Checkbox';
|
||||
@@ -16,12 +16,6 @@ import { LabCaseTrackerCard } from '@/components/ui/treatment/LabCaseTrackerCard
|
||||
import { treatmentTypeLabelFromCatalog } from '@/components/shared/treatmentTypeDisplay';
|
||||
import { treatmentsApi } from '@/lib/api/treatments';
|
||||
import { prosthesisCatalogApi } from '@/lib/api/prosthesis-catalog';
|
||||
import {
|
||||
lastProsthesisTypeForLab,
|
||||
loadLabDispatchDefaults,
|
||||
rememberLastLab,
|
||||
rememberLastProsthesisType,
|
||||
} from '@/components/treatment/labDispatchDefaults';
|
||||
import type { ProsthesisCatalogEntry, TreatmentCatalogEntry } from '@/types/treatment-catalog';
|
||||
import type { LabCaseDraft, LinkedOrganizationOption, TreatmentDetailDraft } from '@/types/treatment';
|
||||
import type { PatientLabCaseSummary } from '@/types/lab-case-activity';
|
||||
@@ -34,7 +28,6 @@ interface LabCasesDispatchPanelProps {
|
||||
labCases: LabCaseDraft[];
|
||||
labDependentCodes: Set<string>;
|
||||
treatmentCatalog: TreatmentCatalogEntry[];
|
||||
clinicOrganizationId?: string | null;
|
||||
labCaseSummary?: PatientLabCaseSummary | null;
|
||||
locale: string;
|
||||
onLabCaseSummaryChange?: (summary: PatientLabCaseSummary) => void;
|
||||
@@ -48,7 +41,6 @@ interface LabCasesDispatchPanelProps {
|
||||
organizationSearch: string;
|
||||
onOrganizationSearchChange: (value: string) => void;
|
||||
recentOrganizationIds: string[];
|
||||
onRecentOrganizationPick: (orgId: string) => void;
|
||||
canInviteLab?: boolean;
|
||||
onInviteLab?: () => void;
|
||||
sendBusyId: string | null;
|
||||
@@ -124,7 +116,6 @@ export function LabCasesDispatchPanel({
|
||||
labCases,
|
||||
labDependentCodes,
|
||||
treatmentCatalog,
|
||||
clinicOrganizationId,
|
||||
labCaseSummary,
|
||||
locale,
|
||||
onLabCaseSummaryChange,
|
||||
@@ -138,7 +129,6 @@ export function LabCasesDispatchPanel({
|
||||
organizationSearch,
|
||||
onOrganizationSearchChange,
|
||||
recentOrganizationIds,
|
||||
onRecentOrganizationPick,
|
||||
canInviteLab = false,
|
||||
onInviteLab,
|
||||
sendBusyId,
|
||||
@@ -150,7 +140,6 @@ export function LabCasesDispatchPanel({
|
||||
const [prosthesisOptions, setProsthesisOptions] = useState<ProsthesisCatalogEntry[]>([]);
|
||||
const [applyAllProsthesis, setApplyAllProsthesis] = useState('');
|
||||
const [pendingComment, setPendingComment] = useState('');
|
||||
const autoFilledCaseRef = useRef<string | null>(null);
|
||||
const hasTrackerSummary = Boolean(labCaseSummary && labCaseSummary.labCaseId);
|
||||
|
||||
const activeLinkedOrganizations = orgs.filter((o) => o.active);
|
||||
@@ -168,7 +157,14 @@ export function LabCasesDispatchPanel({
|
||||
|
||||
const activeLabCase =
|
||||
labCaseForActiveDetail ??
|
||||
(activeLabCaseId ? labCases.find((lc) => lc.clientId === activeLabCaseId) : null);
|
||||
(activeLabCaseId
|
||||
? labCases.find(
|
||||
(lc) =>
|
||||
lc.clientId === activeLabCaseId &&
|
||||
(lc.detailClientId == null || lc.detailClientId === activeDetailId),
|
||||
)
|
||||
: null) ??
|
||||
null;
|
||||
|
||||
const sent = Boolean(activeLabCase?.sentAt);
|
||||
const activeDetailNumber = details.findIndex((d) => d.clientId === activeDetailId) + 1;
|
||||
@@ -208,6 +204,7 @@ export function LabCasesDispatchPanel({
|
||||
|
||||
useEffect(() => {
|
||||
setPendingComment('');
|
||||
setApplyAllProsthesis('');
|
||||
}, [activeLabCase?.clientId]);
|
||||
|
||||
function updateActiveLabCase(patch: Partial<LabCaseDraft>) {
|
||||
@@ -226,45 +223,6 @@ export function LabCasesDispatchPanel({
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps -- only sync newly uploaded files
|
||||
}, [activeDetail?.attachmentMetas, activeLabCase?.clientId, sent]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!activeLabCase || sent || activeLabCase.destinationOrganizationId) return;
|
||||
const lastLabId = loadLabDispatchDefaults(clinicOrganizationId).lastLabId;
|
||||
const lastLab = lastLabId
|
||||
? activeLinkedOrganizations.find((o) => o.id === lastLabId)
|
||||
: undefined;
|
||||
if (!lastLab) return;
|
||||
updateActiveLabCase({ destinationOrganizationId: lastLab.id, toothProsthesis: [] });
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [activeLabCase?.clientId, clinicOrganizationId, sent]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!activeLabCase || sent) return;
|
||||
if (!activeLabCase.destinationOrganizationId) return;
|
||||
if (prosthesisOptions.length === 0 || prosthesisRows.length === 0) return;
|
||||
const fillKey = `${activeLabCase.clientId}:${prosthesisRows.length}`;
|
||||
if (autoFilledCaseRef.current === fillKey) return;
|
||||
if (isProsthesisMapComplete(activeLabCase, prosthesisRows)) {
|
||||
autoFilledCaseRef.current = fillKey;
|
||||
return;
|
||||
}
|
||||
const lastCode = lastProsthesisTypeForLab(
|
||||
clinicOrganizationId,
|
||||
activeLabCase.destinationOrganizationId,
|
||||
);
|
||||
if (!lastCode || !prosthesisOptions.some((opt) => opt.code === lastCode)) return;
|
||||
autoFilledCaseRef.current = fillKey;
|
||||
setApplyAllProsthesis(lastCode);
|
||||
updateActiveLabCase({ toothProsthesis: toothProsthesisForRows(prosthesisRows, lastCode) });
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [
|
||||
activeLabCase?.clientId,
|
||||
activeLabCase?.destinationOrganizationId,
|
||||
clinicOrganizationId,
|
||||
prosthesisOptions,
|
||||
prosthesisRows.length,
|
||||
sent,
|
||||
]);
|
||||
|
||||
if (!activeDetail || !isLabDependentDetail) {
|
||||
return null;
|
||||
}
|
||||
@@ -287,25 +245,11 @@ export function LabCasesDispatchPanel({
|
||||
]
|
||||
: rest;
|
||||
updateActiveLabCase({ toothProsthesis: next });
|
||||
if (prosthesisTypeCode && activeLabCase.destinationOrganizationId) {
|
||||
rememberLastProsthesisType(
|
||||
clinicOrganizationId,
|
||||
activeLabCase.destinationOrganizationId,
|
||||
prosthesisTypeCode,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function applyProsthesisToAll(code: string) {
|
||||
if (!activeLabCase || !code) return;
|
||||
updateActiveLabCase({ toothProsthesis: toothProsthesisForRows(prosthesisRows, code) });
|
||||
if (activeLabCase.destinationOrganizationId) {
|
||||
rememberLastProsthesisType(
|
||||
clinicOrganizationId,
|
||||
activeLabCase.destinationOrganizationId,
|
||||
code,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function toggleAttachmentInActiveLabCase(attachmentId: string, checked: boolean) {
|
||||
@@ -317,13 +261,11 @@ export function LabCasesDispatchPanel({
|
||||
}
|
||||
|
||||
function handleSelectOrganization(org: LinkedOrganizationOption) {
|
||||
autoFilledCaseRef.current = null;
|
||||
updateActiveLabCase({
|
||||
destinationOrganizationId: org.id,
|
||||
toothProsthesis: [],
|
||||
});
|
||||
setApplyAllProsthesis('');
|
||||
rememberLastLab(clinicOrganizationId, org.id);
|
||||
}
|
||||
|
||||
const caseFullyComplete = isLabCaseCompleted(activeLabCase?.taskProgress);
|
||||
@@ -463,10 +405,7 @@ export function LabCasesDispatchPanel({
|
||||
key={o.id}
|
||||
type="button"
|
||||
disabled={disabled}
|
||||
onClick={() => {
|
||||
handleSelectOrganization(o);
|
||||
onRecentOrganizationPick(o.id);
|
||||
}}
|
||||
onClick={() => handleSelectOrganization(o)}
|
||||
className="text-xs rounded-[var(--radius-sm)] border border-border/70 px-2 py-1 text-text-secondary hover:text-text-primary hover:border-border focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/35 disabled:opacity-50"
|
||||
>
|
||||
{o.name}
|
||||
@@ -615,26 +554,7 @@ export function LabCasesDispatchPanel({
|
||||
!prosthesisComplete
|
||||
}
|
||||
isLoading={sendBusyId === activeLabCase.clientId}
|
||||
onClick={() => {
|
||||
if (activeLabCase.destinationOrganizationId) {
|
||||
rememberLastLab(clinicOrganizationId, activeLabCase.destinationOrganizationId);
|
||||
const codes = [
|
||||
...new Set(
|
||||
activeLabCase.toothProsthesis
|
||||
.map((tp) => tp.prosthesisTypeCode)
|
||||
.filter(Boolean),
|
||||
),
|
||||
];
|
||||
if (codes.length === 1) {
|
||||
rememberLastProsthesisType(
|
||||
clinicOrganizationId,
|
||||
activeLabCase.destinationOrganizationId,
|
||||
codes[0],
|
||||
);
|
||||
}
|
||||
}
|
||||
return onSendLabCase(activeLabCase, pendingComment.trim());
|
||||
}}
|
||||
onClick={() => onSendLabCase(activeLabCase, pendingComment.trim())}
|
||||
>
|
||||
{t('sendToLab')}
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user