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)
}
export async function editOrder(editOrderForm) {
return await update(API.ORDERTEST, editOrderForm)
export async function editOrder(editOrderForm, id) {
return await update(API.ORDERTEST, editOrderForm, id)
}

View File

@ -5,6 +5,8 @@
import { toast } from "svelte-sonner";
import ReusableAlertDialog from "$lib/components/reusable/reusable-alert-dialog.svelte";
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();
@ -51,6 +53,31 @@ $inspect(formState.form)
</script>
<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
{formState}
formFields={formFields}

View File

@ -5,6 +5,8 @@
import { toast } from "svelte-sonner";
import ReusableAlertDialog from "$lib/components/reusable/reusable-alert-dialog.svelte";
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();
@ -16,21 +18,66 @@
let showConfirm = $state(false);
async function handleEdit() {
console.log('edit');
// const payload = buildOrderTestPayload(formState.form);
// console.log(payload);
function diffTests(current = [], original = []) {
const currentIds = new Set(current.map(t => t.TestSiteID));
const originalIds = new Set(original.map(t => t.TestSiteID));
// const result = await formState.save(masterDetail.mode, payload);
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() {
const currentPayload = formState.form;
const originalPayload = masterDetail.formSnapshot;
const changedFields = getChangedFields(originalPayload, currentPayload);
const { added, deleted } = diffTests(
currentPayload.Tests ?? [],
originalPayload.Tests ?? []
);
const hasMainChanges = Object.keys(changedFields).length > 0;
const hasTestChanges = added.length > 0 || deleted.length > 0;
if (Object.keys(changedFields).length === 0) {
toast('No changes detected');
return;
}
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 Created!');
// masterDetail?.exitForm(true);
// } else {
// console.error('Failed to save order test');
// const errorMessages = result.messages ? Object.values(result.messages).join('\n') : 'Failed to save order test';
// toast.error(errorMessages)
// }
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({
@ -52,10 +99,10 @@
// idCounter = maxId;
// }
// });
$inspect(formState.form.Tests)
$inspect(formState.form)
</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
{formState}
formFields={formFields}

View File

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

View File

@ -5,6 +5,7 @@
import ReusableEmpty from "$lib/components/reusable/reusable-empty.svelte";
import * as Table from "$lib/components/ui/table/index.js";
import { Spinner } from "$lib/components/ui/spinner/index.js";
import ClipboardXIcon from "@lucide/svelte/icons/clipboard-x";
let props = $props();
@ -46,8 +47,8 @@
<Table.Row>
<Table.Head>Test Code</Table.Head>
<Table.Head>Test Name</Table.Head>
<Table.Head>Discipline</Table.Head>
<Table.Head>Create Date</Table.Head>
<!-- <Table.Head>Discipline</Table.Head> -->
<!-- <Table.Head>Create Date</Table.Head> -->
</Table.Row>
</Table.Header>
<Table.Body>
@ -55,8 +56,8 @@
<Table.Row>
<Table.Cell>{row.TestSiteCode ?? '-'}</Table.Cell>
<Table.Cell>{row.TestSiteName ?? '-'}</Table.Cell>
<Table.Cell>{row.Discipline.DisciplineName ?? '-'}</Table.Cell>
<Table.Cell>{formatUTCDate(row.CreateDate) ?? '-'}</Table.Cell>
<!-- <Table.Cell>{row.Discipline.DisciplineName ?? '-'}</Table.Cell> -->
<!-- <Table.Cell>{row.CreateDate}</Table.Cell> -->
</Table.Row>
{/each}
</Table.Body>
@ -126,5 +127,5 @@
</div>
</div>
{:else}
<ReusableEmpty desc="Select a visit to see details"/>
<ReusableEmpty icon={ClipboardXIcon} desc="Select an order to see details"/>
{/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.Row class="hover:bg-transparent">
<Table.Head class="w-[40px]">No</Table.Head>
<Table.Head>Test Name</Table.Head>
<Table.Head>Test Code</Table.Head>
<Table.Head>Test Name</Table.Head>
<Table.Head class="w-[40px]"></Table.Head>
</Table.Row>
</Table.Header>
@ -307,8 +307,8 @@
class="cursor-pointer hover:bg-muted/50"
>
<Table.Cell>{index + 1}</Table.Cell>
<Table.Cell>{test.TestSiteName}</Table.Cell>
<Table.Cell>{test.TestSiteCode}</Table.Cell>
<Table.Cell>{test.TestSiteName}</Table.Cell>
<Table.Cell>
<div class="flex gap-1">
<Tooltip.Provider>

View File

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