continue ordertest

ordertest edit page
change selectedPatient & selectedVisit using order stores
This commit is contained in:
faiztyanirh 2026-04-23 13:54:06 +07:00
parent f8af8c21e6
commit e236a20527
8 changed files with 123 additions and 38 deletions

View File

@ -17,6 +17,6 @@ export async function createOrder(newOrderForm) {
return await create(API.ORDERTEST, newOrderForm) return await create(API.ORDERTEST, newOrderForm)
} }
export async function editOrder(editOrderForm) { export async function editOrder(editOrderForm, id) {
return await update(API.ORDERTEST, editOrderForm) return await update(API.ORDERTEST, editOrderForm, id)
} }

View File

@ -5,6 +5,8 @@
import { toast } from "svelte-sonner"; import { toast } from "svelte-sonner";
import ReusableAlertDialog from "$lib/components/reusable/reusable-alert-dialog.svelte"; import ReusableAlertDialog from "$lib/components/reusable/reusable-alert-dialog.svelte";
import { buildOrderTestPayload } from "$lib/components/order/ordertest/config/ordertest-form-config"; import { buildOrderTestPayload } from "$lib/components/order/ordertest/config/ordertest-form-config";
import { orderStore } from "$lib/components/order/ordertest/store/order-store.svelte";
import { formatUTCDate } from "$lib/utils/formatUTCDate";
let props = $props(); let props = $props();
@ -51,6 +53,31 @@ $inspect(formState.form)
</script> </script>
<FormPageContainer title="Create Order for {formState.form?.PatientID} - {formState.form?.PatientName}" {primaryAction} {secondaryActions} {actions}> <FormPageContainer title="Create Order for {formState.form?.PatientID} - {formState.form?.PatientName}" {primaryAction} {secondaryActions} {actions}>
{#if orderStore.selectedPatient}
<div class="flex justify-between w-full rounded-md border p-2">
<div class="flex flex-col">
<span class="font-bold tracking-wide underline">
{orderStore.selectedPatient?.PatientID}
</span>
<span class="font-semibold">
{orderStore.selectedPatient?.FullName}
</span>
<span class="text-xs">
{orderStore.selectedPatient?.Age ? orderStore.selectedPatient.Age.split(' ').slice(0, 2).join(' ') : 'N/A'} -
{orderStore.selectedPatient?.SexLabel} -
{orderStore.selectedPatient?.BirthdateConversion}
</span>
</div>
<div class="flex flex-col justify-end items-end">
<span class="font-bold tracking-wide underline">
{orderStore.selectedVisit?.PVID}
</span>
<span class="text-xs">
{formatUTCDate(orderStore.selectedVisit?.PVCreateDate)}
</span>
</div>
</div>
{/if}
<OrderFormRenderer <OrderFormRenderer
{formState} {formState}
formFields={formFields} formFields={formFields}

View File

@ -5,6 +5,8 @@
import { toast } from "svelte-sonner"; import { toast } from "svelte-sonner";
import ReusableAlertDialog from "$lib/components/reusable/reusable-alert-dialog.svelte"; import ReusableAlertDialog from "$lib/components/reusable/reusable-alert-dialog.svelte";
import { buildOrderTestPayload } from "$lib/components/order/ordertest/config/ordertest-form-config"; import { buildOrderTestPayload } from "$lib/components/order/ordertest/config/ordertest-form-config";
import { getChangedFields } from "$lib/utils/getChangedFields";
import { orderStore } from "$lib/components/order/ordertest/store/order-store.svelte";
let props = $props(); let props = $props();
@ -16,21 +18,66 @@
let showConfirm = $state(false); let showConfirm = $state(false);
function diffTests(current = [], original = []) {
const currentIds = new Set(current.map(t => t.TestSiteID));
const originalIds = new Set(original.map(t => t.TestSiteID));
const added = current
.filter(t => !originalIds.has(t.TestSiteID))
.map(t => ({
TestSiteID: t.TestSiteID
}));
const deleted = original
.filter(t => !currentIds.has(t.TestSiteID))
.map(t => ({
TestSiteID: t.TestSiteID
}));
return { added, deleted };
}
async function handleEdit() { async function handleEdit() {
console.log('edit'); const currentPayload = formState.form;
// const payload = buildOrderTestPayload(formState.form); const originalPayload = masterDetail.formSnapshot;
// console.log(payload); const changedFields = getChangedFields(originalPayload, currentPayload);
// const result = await formState.save(masterDetail.mode, payload); const { added, deleted } = diffTests(
currentPayload.Tests ?? [],
originalPayload.Tests ?? []
);
// if (result.status === 'success') { const hasMainChanges = Object.keys(changedFields).length > 0;
// toast('Order Test Created!'); const hasTestChanges = added.length > 0 || deleted.length > 0;
// masterDetail?.exitForm(true);
// } else { if (Object.keys(changedFields).length === 0) {
// console.error('Failed to save order test'); toast('No changes detected');
// const errorMessages = result.messages ? Object.values(result.messages).join('\n') : 'Failed to save order test'; return;
// toast.error(errorMessages) }
// }
const payload = {
OrderID: formState.form.OrderID,
...changedFields,
...(hasTestChanges && {
Tests: {
added,
deleted
}
})
};
console.log('Payload:', payload);
const result = await formState.save(masterDetail.mode, payload);
if (result.status === 'success') {
toast('Order Test Updated!');
masterDetail?.exitForm(true);
} else {
console.error('Failed to update order test');
const errorMessages = result.messages ? Object.values(result.messages).join('\n') : 'Failed to update order test';
toast.error(errorMessages)
}
} }
const primaryAction = $derived({ const primaryAction = $derived({
@ -52,10 +99,10 @@
// idCounter = maxId; // idCounter = maxId;
// } // }
// }); // });
$inspect(formState.form.Tests) $inspect(formState.form)
</script> </script>
<FormPageContainer title="Edit Order for {formState.form?.PatientID} - {formState.form?.PatientName}" {primaryAction} {secondaryActions}> <FormPageContainer title="Edit Order for {orderStore.selectedPatient.PatientID} - {orderStore.selectedPatient.FullName}" {primaryAction} {secondaryActions}>
<OrderFormRenderer <OrderFormRenderer
{formState} {formState}
formFields={formFields} formFields={formFields}

View File

@ -15,18 +15,19 @@
import { getPatient } from "$lib/components/patient/list/api/patient-list-api"; import { getPatient } from "$lib/components/patient/list/api/patient-list-api";
import { patientStore } from "$lib/components/patient/list/store/patient-store.svelte"; import { patientStore } from "$lib/components/patient/list/store/patient-store.svelte";
import { formatUTCDate } from "$lib/utils/formatUTCDate"; import { formatUTCDate } from "$lib/utils/formatUTCDate";
import { orderStore } from "$lib/components/order/ordertest/store/order-store.svelte";
let props = $props(); let props = $props();
let selectedPatient = $state(null); // let selectedPatient = $state(null);
let selectedVisit = $state(null); // let selectedVisit = $state(null);
let isLoading = $state(false); let isLoading = $state(false);
let searchData = $state([]); let searchData = $state([]);
const search = useSearch(searchFields, searchParam); const search = useSearch(searchFields, searchParam);
let actions = $derived.by(() => { let actions = $derived.by(() => {
return orderTestActions(props.masterDetail, selectedPatient, selectedVisit).map(action => { return orderTestActions(props.masterDetail, orderStore.selectedPatient, orderStore.selectedVisit).map(action => {
if (action.label === 'Search Parameters') { if (action.label === 'Search Parameters') {
return { ...action, popoverContent: searchParamSnippet }; return { ...action, popoverContent: searchParamSnippet };
} }
@ -37,12 +38,12 @@
let activeRowId = $state(null); let activeRowId = $state(null);
async function handlePatientConfirm(patient, visit) { async function handlePatientConfirm(patient, visit) {
selectedPatient = patient; orderStore.selectedPatient = patient;
selectedVisit = visit; orderStore.selectedVisit = visit;
isLoading = true; isLoading = true;
try { try {
searchData = await getOrderList({ searchData = await getOrderList({
PVADTID: selectedVisit.PVADTID PVADTID: orderStore.selectedVisit.PVADTID
}); });
} catch (error) { } catch (error) {
console.error('Search failed:', error); console.error('Search failed:', error);
@ -73,6 +74,8 @@
patientStore.pending = null; patientStore.pending = null;
} }
}) })
$inspect(orderStore)
</script> </script>
{#snippet searchParamSnippet()} {#snippet searchParamSnippet()}
@ -109,27 +112,27 @@
} }
}}> }}>
<TopbarWrapper {actions}/> <TopbarWrapper {actions}/>
{#if selectedPatient} {#if orderStore.selectedPatient}
<div class="flex justify-between w-full rounded-md border p-2"> <div class="flex justify-between w-full rounded-md border p-2">
<div class="flex flex-col"> <div class="flex flex-col">
<span class="font-bold tracking-wide underline"> <span class="font-bold tracking-wide underline">
{selectedPatient?.PatientID} {orderStore.selectedPatient?.PatientID}
</span> </span>
<span class="font-semibold"> <span class="font-semibold">
{selectedPatient?.FullName} {orderStore.selectedPatient?.FullName}
</span> </span>
<span class="text-xs"> <span class="text-xs">
{selectedPatient?.Age ? selectedPatient.Age.split(' ').slice(0, 2).join(' ') : 'N/A'} - {orderStore.selectedPatient?.Age ? orderStore.selectedPatient.Age.split(' ').slice(0, 2).join(' ') : 'N/A'} -
{selectedPatient?.SexLabel} - {orderStore.selectedPatient?.SexLabel} -
{selectedPatient?.BirthdateConversion} {orderStore.selectedPatient?.BirthdateConversion}
</span> </span>
</div> </div>
<div class="flex flex-col justify-end items-end"> <div class="flex flex-col justify-end items-end">
<span class="font-bold tracking-wide underline"> <span class="font-bold tracking-wide underline">
{selectedVisit?.PVID} {orderStore.selectedVisit?.PVID}
</span> </span>
<span class="text-xs"> <span class="text-xs">
{formatUTCDate(selectedVisit?.PVCreateDate)} {formatUTCDate(orderStore.selectedVisit?.PVCreateDate)}
</span> </span>
</div> </div>
</div> </div>

View File

@ -5,6 +5,7 @@
import ReusableEmpty from "$lib/components/reusable/reusable-empty.svelte"; import ReusableEmpty from "$lib/components/reusable/reusable-empty.svelte";
import * as Table from "$lib/components/ui/table/index.js"; import * as Table from "$lib/components/ui/table/index.js";
import { Spinner } from "$lib/components/ui/spinner/index.js"; import { Spinner } from "$lib/components/ui/spinner/index.js";
import ClipboardXIcon from "@lucide/svelte/icons/clipboard-x";
let props = $props(); let props = $props();
@ -46,8 +47,8 @@
<Table.Row> <Table.Row>
<Table.Head>Test Code</Table.Head> <Table.Head>Test Code</Table.Head>
<Table.Head>Test Name</Table.Head> <Table.Head>Test Name</Table.Head>
<Table.Head>Discipline</Table.Head> <!-- <Table.Head>Discipline</Table.Head> -->
<Table.Head>Create Date</Table.Head> <!-- <Table.Head>Create Date</Table.Head> -->
</Table.Row> </Table.Row>
</Table.Header> </Table.Header>
<Table.Body> <Table.Body>
@ -55,8 +56,8 @@
<Table.Row> <Table.Row>
<Table.Cell>{row.TestSiteCode ?? '-'}</Table.Cell> <Table.Cell>{row.TestSiteCode ?? '-'}</Table.Cell>
<Table.Cell>{row.TestSiteName ?? '-'}</Table.Cell> <Table.Cell>{row.TestSiteName ?? '-'}</Table.Cell>
<Table.Cell>{row.Discipline.DisciplineName ?? '-'}</Table.Cell> <!-- <Table.Cell>{row.Discipline.DisciplineName ?? '-'}</Table.Cell> -->
<Table.Cell>{formatUTCDate(row.CreateDate) ?? '-'}</Table.Cell> <!-- <Table.Cell>{row.CreateDate}</Table.Cell> -->
</Table.Row> </Table.Row>
{/each} {/each}
</Table.Body> </Table.Body>
@ -126,5 +127,5 @@
</div> </div>
</div> </div>
{:else} {:else}
<ReusableEmpty desc="Select a visit to see details"/> <ReusableEmpty icon={ClipboardXIcon} desc="Select an order to see details"/>
{/if} {/if}

View File

@ -0,0 +1,6 @@
export const orderStore = $state({
selectedPatient: null,
selectedVisit: null,
});
// export const patientStore = $state({ pending: null });

View File

@ -289,8 +289,8 @@
<Table.Header> <Table.Header>
<Table.Row class="hover:bg-transparent"> <Table.Row class="hover:bg-transparent">
<Table.Head class="w-[40px]">No</Table.Head> <Table.Head class="w-[40px]">No</Table.Head>
<Table.Head>Test Name</Table.Head>
<Table.Head>Test Code</Table.Head> <Table.Head>Test Code</Table.Head>
<Table.Head>Test Name</Table.Head>
<Table.Head class="w-[40px]"></Table.Head> <Table.Head class="w-[40px]"></Table.Head>
</Table.Row> </Table.Row>
</Table.Header> </Table.Header>
@ -307,8 +307,8 @@
class="cursor-pointer hover:bg-muted/50" class="cursor-pointer hover:bg-muted/50"
> >
<Table.Cell>{index + 1}</Table.Cell> <Table.Cell>{index + 1}</Table.Cell>
<Table.Cell>{test.TestSiteName}</Table.Cell>
<Table.Cell>{test.TestSiteCode}</Table.Cell> <Table.Cell>{test.TestSiteCode}</Table.Cell>
<Table.Cell>{test.TestSiteName}</Table.Cell>
<Table.Cell> <Table.Cell>
<div class="flex gap-1"> <div class="flex gap-1">
<Tooltip.Provider> <Tooltip.Provider>

View File

@ -20,6 +20,7 @@
modeOpt: 'default', modeOpt: 'default',
saveEndpoint: createOrder, saveEndpoint: createOrder,
editEndpoint: editOrder, editEndpoint: editOrder,
idKey: 'OrderID',
mapToForm: (data) => ({ mapToForm: (data) => ({
...data, ...data,
Tests: (data.Tests || []).map((t, i) => ({ Tests: (data.Tests || []).map((t, i) => ({