diff --git a/src/lib/components/composable/use-dictionary-form.svelte.js b/src/lib/components/composable/use-dictionary-form.svelte.js index 03999be..94a93ea 100644 --- a/src/lib/components/composable/use-dictionary-form.svelte.js +++ b/src/lib/components/composable/use-dictionary-form.svelte.js @@ -25,7 +25,7 @@ // } // } -export function useDictionaryForm(formState, getActiveFormStates) { +export function useDictionaryForm(formState, getActiveFormStates = () => ({})) { let hasErrors = $derived.by(() => { const mainHasError = Object.values(formState.errors).some(v => v !== null); const activeHasError = Object.values(getActiveFormStates()).some(fs => diff --git a/src/lib/components/composable/use-master-detail.svelte.js b/src/lib/components/composable/use-master-detail.svelte.js index a063547..d043226 100644 --- a/src/lib/components/composable/use-master-detail.svelte.js +++ b/src/lib/components/composable/use-master-detail.svelte.js @@ -29,7 +29,7 @@ export function useMasterDetail(options = {}) { const isDirty = $derived( JSON.stringify(formState.form) !== JSON.stringify(formSnapshot) ); -// $inspect(formSnapshot) +// $inspect(formState.form) async function select(item) { mode = "view"; diff --git a/src/lib/components/composable/use-patient-form.svelte.js b/src/lib/components/composable/use-patient-form.svelte.js index 152ab20..5c16b5a 100644 --- a/src/lib/components/composable/use-patient-form.svelte.js +++ b/src/lib/components/composable/use-patient-form.svelte.js @@ -40,17 +40,17 @@ export function usePatientForm(formState, patientSchema) { } function validateIdentifier() { - const identifierType = formState.form.PatIdt?.IdentifierType; - const identifierValue = formState.form.PatIdt?.Identifier; + const identifierType = formState.form.PatIdt_IdentifierType; + const identifierValue = formState.form.PatIdt_Identifier; if (!identifierType || !identifierValue) { - formState.errors['PatIdt.Identifier'] = null; + formState.errors.PatIdt_Identifier = null; return; } const schema = getIdentifierValidation(identifierType); const result = schema.safeParse(identifierValue); - formState.errors['PatIdt.Identifier'] = result.success ? null : result.error.issues[0].message; + formState.errors.PatIdt_Identifier = result.success ? null : result.error.issues[0].message; } function getIdentifierValidation(identifierType) { diff --git a/src/lib/components/dictionary/test/config/test-form-config.js b/src/lib/components/dictionary/test/config/test-form-config.js index eb7359e..19a9f25 100644 --- a/src/lib/components/dictionary/test/config/test-form-config.js +++ b/src/lib/components/dictionary/test/config/test-form-config.js @@ -726,18 +726,19 @@ export const refNumFormFields = [ { type: 'row', columns: [ - { - key: 'NumRefType', - label: 'Reference Type', - required: false, - type: 'text' - }, + // { + // key: 'NumRefType', + // label: 'Reference Type', + // required: false, + // type: 'text' + // }, { key: 'RangeType', label: 'Range Type', required: false, type: 'select', - optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/range_type` + optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/range_type`, + fullWidth: false } ] }, diff --git a/src/lib/components/dictionary/test/page/tabs/calculation09032026.svelte b/src/lib/components/dictionary/test/page/tabs/calculation09032026.svelte deleted file mode 100644 index a64e426..0000000 --- a/src/lib/components/dictionary/test/page/tabs/calculation09032026.svelte +++ /dev/null @@ -1,128 +0,0 @@ - - -
- -
\ No newline at end of file diff --git a/src/lib/components/dictionary/test/page/tabs/ref-num.svelte b/src/lib/components/dictionary/test/page/tabs/ref-num.svelte index ada7670..7654e46 100644 --- a/src/lib/components/dictionary/test/page/tabs/ref-num.svelte +++ b/src/lib/components/dictionary/test/page/tabs/ref-num.svelte @@ -54,7 +54,14 @@ } function resetForm() { + const currentRefType = props.refNumState.form.NumRefType; + props.refNumState.reset?.(); + + if (currentRefType) { + props.refNumState.form.NumRefType = currentRefType; + } + joinFields = { AgeStart: { DD: '', MM: '', YY: '' }, AgeEnd: { DD: '', MM: '', YY: '' } diff --git a/src/lib/components/patient/admission/page/create-page copy.svelte b/src/lib/components/patient/admission/page/create-page copy.svelte deleted file mode 100644 index e2d3153..0000000 --- a/src/lib/components/patient/admission/page/create-page copy.svelte +++ /dev/null @@ -1,62 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/lib/components/patient/list/config/patient-config.js b/src/lib/components/patient/list/config/patient-config.js index f02ec6c..2c2dcea 100644 --- a/src/lib/components/patient/list/config/patient-config.js +++ b/src/lib/components/patient/list/config/patient-config.js @@ -52,7 +52,7 @@ export const detailSections = [ isGroup: true, class: "grid grid-cols-2", fields: [ - { key: "City", label: "City" }, + { key: "CityLabel", label: "City" }, { key: "ZIP", label: "ZIP" }, ], }, @@ -62,7 +62,7 @@ export const detailSections = [ isGroup: true, class: "grid grid-cols-2", fields: [ - { key: "Province", label: "Province" }, + { key: "ProvinceLabel", label: "Province" }, { key: "CountryLabel", label: "Country" }, ], }, diff --git a/src/lib/components/patient/list/config/patient-form-config.js b/src/lib/components/patient/list/config/patient-form-config.js index 9b9862a..de396d8 100644 --- a/src/lib/components/patient/list/config/patient-form-config.js +++ b/src/lib/components/patient/list/config/patient-form-config.js @@ -20,10 +20,8 @@ export const patientSchema = z.object({ export const patientInitialForm = { PatientID: "", AlternatePID: "", - PatIdt: { - IdentifierType: "", - Identifier: "" - }, + PatIdt_IdentifierType: "", + PatIdt_Identifier: "", NameFirst: "", Prefix: "", Sex: "", @@ -32,10 +30,8 @@ export const patientInitialForm = { NameMaiden: "", MaritalStatus: "", NameLast: "", - Custodian: { - InternalPID: "", - PatientID: "" - }, + Custodian_InternalPID: "", + Custodian_PatientID: "", Ethnic: "", Suffix: "", PlaceOfBirth: "", @@ -69,7 +65,7 @@ export const patientDefaultErrors = { Birthdate: "Required", EmailAddress1: null, EmailAddress2: null, - 'PatIdt.Identifier': null, + PatIdt_Identifier: null, Phone: null, MobilePhone: null, }; @@ -95,7 +91,7 @@ export const patientFormFields = [ type: "text" }, { - key: "PatIdt.Identifier", + key: "PatIdt_Identifier", label: "Identifier", required: false, type: "identity", @@ -310,4 +306,26 @@ export function getPatientFormActions(handlers) { onClick: handlers.clearForm, }, ]; +} + +export function buildPatientPayload(form) { + const { + PatIdt_IdentifierType, + PatIdt_Identifier, + Custodian_InternalPID, + Custodian_PatientID, + ...rest + } = form; + + return { + ...rest, + PatIdt: { + IdentifierType: PatIdt_IdentifierType, + Identifier: PatIdt_Identifier + }, + Custodian: { + InternalPID: Custodian_InternalPID, + PatientID: Custodian_PatientID + } + }; } \ No newline at end of file diff --git a/src/lib/components/patient/list/modal/custodian-modal.svelte b/src/lib/components/patient/list/modal/custodian-modal.svelte index 75a17a4..e607152 100644 --- a/src/lib/components/patient/list/modal/custodian-modal.svelte +++ b/src/lib/components/patient/list/modal/custodian-modal.svelte @@ -28,17 +28,18 @@ isOpen = open; if (open) { - if (props.formState.form.Custodian) { + if (props.formState.form.Custodian_PatientID) { selectedPatient = { - InternalPID: props.formState.form.Custodian.InternalPID || null, - PatientID: props.formState.form.Custodian.PatientID || null, + InternalPID: props.formState.form.Custodian_InternalPID || null, + PatientID: props.formState.form.Custodian_PatientID || null, }; } } } function confirmCustodian() { - props.formState.form.Custodian = { ...selectedPatient }; + props.formState.form.Custodian_InternalPID = selectedPatient.InternalPID + props.formState.form.Custodian_PatientID = selectedPatient.PatientID selectedPatient = { InternalPID: null, PatientID: null }; isOpen = false; @@ -46,7 +47,12 @@ function populateCustodian() { custodianModalMode.mode = mode; - setSelectedPatient(editPatientForm.Custodian); + if (props.formState.form.Custodian_PatientID) { + selectedPatient = { + InternalPID: props.formState.form.Custodian_InternalPID, + PatientID: props.formState.form.Custodian_PatientID, + } + } } function togglePatientSelection(patient) { diff --git a/src/lib/components/patient/list/page/create-page copy.svelte b/src/lib/components/patient/list/page/create-page copy.svelte deleted file mode 100644 index a758f72..0000000 --- a/src/lib/components/patient/list/page/create-page copy.svelte +++ /dev/null @@ -1,403 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/src/lib/components/patient/list/page/create-page.svelte b/src/lib/components/patient/list/page/create-page.svelte index 79c7934..a9ee608 100644 --- a/src/lib/components/patient/list/page/create-page.svelte +++ b/src/lib/components/patient/list/page/create-page.svelte @@ -4,6 +4,7 @@ import PatientFormRenderer from "$lib/components/patient/reusable/patient-form-renderer.svelte"; import { toast } from "svelte-sonner"; import ReusableAlertDialog from "$lib/components/reusable/reusable-alert-dialog.svelte"; + import { buildPatientPayload } from "$lib/components/patient/list/config/patient-form-config"; let props = $props(); @@ -29,13 +30,14 @@ showConfirm = true; } } - +// $inspect(formState.form) function confirmDiscard() { masterDetail.exitForm(true); } async function handleSave() { - const result = await formState.save(masterDetail.mode); + const payload = buildPatientPayload(formState.form); + const result = await formState.save(masterDetail.mode, payload); if (result.status === 'success') { toast('Patient Created!'); diff --git a/src/lib/components/patient/list/page/edit-page copy.svelte b/src/lib/components/patient/list/page/edit-page copy.svelte deleted file mode 100644 index 9b945a1..0000000 --- a/src/lib/components/patient/list/page/edit-page copy.svelte +++ /dev/null @@ -1,523 +0,0 @@ - - -{#snippet Fieldset({ key, label, required, type, optionsEndpoint, options, validateOn, dependsOn, endpointParamKey })} -
-
- - {#if required} - * - {/if} -
- -
- {#if type === "input" || type === "email" || type === "number"} - { - if (validateOn?.includes("input")) { - formState.validateField(key); - } - }} - onblur={() => { - if (validateOn?.includes("blur")) { - validateFieldAsync(key); - } - }} - /> - {:else if type === "date"} - { - formState.form[key] = dateStr; - if (validateOn?.includes("input")) { - formState.validateField(key, dateStr, false); - } - }} - /> - {:else if type === "datetime"} - - - {:else if type === "textarea"} - - {:else if type === "select"} - {@const selectedLabel = formState.selectOptions[key]?.find(opt => opt.value === formState.form[key])?.label || "Choose"} - {@const filteredOptions = getFilteredOptions(key)} - { - formState.form[key] = val; - if (validateOn?.includes("input")) { - formState.validateField(key, formState.form[key], false); - } - if (key === "Province") { - formState.form.City = ""; - formState.selectOptions.City = []; - formState.lastFetched.City = null; - } - }} - onOpenChange={(open) => { - if (open && optionsEndpoint) { - formState.fetchOptions({ key, optionsEndpoint, dependsOn, endpointParamKey}, formState.form ); - } - }} - > - - {selectedLabel} - - -
- -
- {#if formState.loadingOptions[key]} - Loading... - {:else} - {#if !required} - - None - - {/if} - {#each filteredOptions as option} - - {option.label} - - {/each} - {/if} -
-
- {:else if type === "identity"} - {@const selectedLabel = formState.selectOptions[key]?.find(opt => opt.value === formState.form.PatIdt.IdentifierType)?.label || "Choose"} -
- { - if (open && optionsEndpoint) { - formState.fetchOptions({ key, optionsEndpoint}); - } - }} - onValueChange={(val) => { - formState.form.PatIdt = { - IdentifierType: val, - Identifier:'' - }; - }} - > - - {selectedLabel} - - - {#if formState.loadingOptions[key]} - Loading... - {:else} - {#if !required} - - None - - {/if} - {#each formState.selectOptions[key] ?? [] as option} - - {option.label} - - {/each} - {/if} - - - -
- {:else if type === "custodian"} -
- - -
- {:else if type === "linkto"} -
- - -
- {:else if type === "fileupload"} -
- - {#if Object.keys(uploadErrors).length > 0} -
- {#each Object.entries(uploadErrors) as [file, msg]} - {msg} - {/each} -
- {/if} -
- {:else} - - {/if} - -
- - {#if isChecking[key]} -
- - Checking... -
- {:else if formState.errors[key]} - - {formState.errors[key]} - - {/if} -
-
-
-{/snippet} - - -
- {#each patientFormFields as group} -
- {#if group.title} -
- {group.title} -
- {/if} - - {#each group.rows as row} -
- {#each row.columns as col} - {#if col.type === "group"} -
- {#each col.columns as child} - {@render Fieldset(child)} - {/each} -
- {:else} - {@render Fieldset(col)} - {/if} - {/each} -
- {/each} -
- {/each} -
-
- - \ No newline at end of file diff --git a/src/lib/components/patient/list/page/edit-page.svelte b/src/lib/components/patient/list/page/edit-page.svelte index b2f97b2..0ec37e9 100644 --- a/src/lib/components/patient/list/page/edit-page.svelte +++ b/src/lib/components/patient/list/page/edit-page.svelte @@ -6,10 +6,10 @@ import { untrack } from "svelte"; import { API } from "$lib/config/api"; import ReusableAlertDialog from "$lib/components/reusable/reusable-alert-dialog.svelte"; + import { buildPatientPayload } from "$lib/components/patient/list/config/patient-form-config"; let props = $props(); - // const { masterDetail, formFields, formActions, schema, initialForm, defaultError } = props.context; const { masterDetail, formFields, formActions, schema, initialForm } = props.context; const { formState } = masterDetail; @@ -30,38 +30,7 @@ } $effect(() => { - // const backendData = masterDetail?.selectedItem?.patient; - // if (!backendData) return; - untrack(() => { - // const formData = { - // ...backendData, - - // PatIdt: backendData.PatIdt ?? initialForm.PatIdt, - // LinkTo: backendData.LinkTo ?? [], - // Custodian: backendData.Custodian ?? initialForm.Custodian, - - // Sex: backendData.SexKey || backendData.Sex, - // Religion: backendData.ReligionKey || backendData.Religion, - // MaritalStatus: backendData.MaritalStatusKey || backendData.MaritalStatus, - // Ethnic: backendData.EthnicKey || backendData.Ethnic, - // Race: backendData.RaceKey || backendData.Race, - // Country: backendData.CountryKey || backendData.Country, - // DeathIndicator: backendData.DeathIndicatorKey || backendData.DeathIndicator, - // Province: backendData.ProvinceID || backendData.Province, - // City: backendData.CityID || backendData.City, - // }; - - // formState.setForm(formData); - - // Ensure PatIdt is always an object to prevent binding errors - // if (!formState.form.PatIdt) { - // formState.form.PatIdt = { - // IdentifierType: "", - // Identifier: "" - // }; - // } - formFields.forEach(group => { group.rows.forEach(row => { row.columns.forEach(col => { @@ -93,11 +62,11 @@ }); }); -// $inspect(masterDetail?.selectedItem?.patient) +$inspect(masterDetail?.selectedItem?.patient) // $inspect(formState.form) async function handleEdit() { - // console.log(formState.form); - const result = await formState.save(masterDetail.mode); + const payload = buildPatientPayload(formState.form); + const result = await formState.save(masterDetail.mode, payload); if (result.status === 'success') { console.log('Patient updated successfully'); diff --git a/src/lib/components/patient/reusable/patient-form-renderer.svelte b/src/lib/components/patient/reusable/patient-form-renderer.svelte index 24318e1..2be932a 100644 --- a/src/lib/components/patient/reusable/patient-form-renderer.svelte +++ b/src/lib/components/patient/reusable/patient-form-renderer.svelte @@ -220,19 +220,18 @@ {:else if type === "identity"} - {@const selectedLabel = formState.selectOptions[key]?.find(opt => opt.value === formState.form.PatIdt?.IdentifierType)?.label || "Choose"} + {@const selectedLabel = formState.selectOptions[key]?.find(opt => opt.value === formState.form.PatIdt_IdentifierType)?.label || "Choose"}
- { if (open && optionsEndpoint) { formState.fetchOptions({ key, optionsEndpoint}); } }} onValueChange={(val) => { - formState.form.PatIdt = { - IdentifierType: val, - Identifier:'' - }; + formState.form.PatIdt_IdentifierType = val; + formState.form.PatIdt_Identifier = '' + formState.errors.PatIdt_Identifier = null }} > @@ -253,11 +252,11 @@ {/if} - +
{:else if type === "custodian"}
- +
{:else if type === "linkto"} diff --git a/src/lib/components/reusable/form/dictionary-form-renderer09032026.svelte b/src/lib/components/reusable/form/dictionary-form-renderer09032026.svelte deleted file mode 100644 index e7689d9..0000000 --- a/src/lib/components/reusable/form/dictionary-form-renderer09032026.svelte +++ /dev/null @@ -1,770 +0,0 @@ - - -{#snippet Fieldset({ - key, - label, - required, - type, - optionsEndpoint, - options, - validateOn, - dependsOn, - endpointParamKey, - valueKey, - labelKey, - txtKey -})} -
-
- - {#if required} - * - {/if} -
- -
- {#if type === 'text'} - { - if (validateOn?.includes('input')) { - formState.validateField(key, formState.form[key], false); - } - }} - onblur={() => { - if (validateOn?.includes('blur')) { - validateFieldAsync(key, mode, originalData?.[key]); - } - }} - readonly={key === 'NumRefType' || key === 'TxtRefType' || key === 'Level'} - /> - {:else if type === 'email'} - { - if (validateOn?.includes('input')) { - formState.validateField(key, formState.form[key], false); - } - }} - onblur={() => { - if (validateOn?.includes('blur')) { - formState.validateField(key, formState.form[key], false); - } - }} - /> - {:else if type === 'number'} - { - if (validateOn?.includes('input')) { - formState.validateField(key, formState.form[key], false); - } - }} - onblur={() => { - if (validateOn?.includes('blur')) { - formState.validateField(key, formState.form[key], false); - } - }} - onkeydown={(e) => ['e', 'E', '+', '-'].includes(e.key) && e.preventDefault()} - /> - {:else if type === 'textarea'} -