diff --git a/src/lib/components/composable/use-form-option.svelte.js b/src/lib/components/composable/use-form-option.svelte.js index 2d2c7e7..a1490d4 100644 --- a/src/lib/components/composable/use-form-option.svelte.js +++ b/src/lib/components/composable/use-form-option.svelte.js @@ -23,7 +23,7 @@ const optionsMode = { if (field.key === 'FormulaInput') { return { ...baseOption, - level: item.SeqRpt, + level: item.CountStat, }; } 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 7f52041..81066f9 100644 --- a/src/lib/components/dictionary/test/config/test-form-config.js +++ b/src/lib/components/dictionary/test/config/test-form-config.js @@ -1,990 +1,1001 @@ -import { API } from "$lib/config/api"; -import EraserIcon from "@lucide/svelte/icons/eraser"; -import { z } from "zod"; -import { cleanEmptyStrings } from "$lib/utils/cleanEmptyStrings"; -import { toDays } from "$lib/utils/ageUtils"; +import { API } from '$lib/config/api'; +import EraserIcon from '@lucide/svelte/icons/eraser'; +import { z } from 'zod'; +import { cleanEmptyStrings } from '$lib/utils/cleanEmptyStrings'; +import { toDays } from '$lib/utils/ageUtils'; -export const testSchema = z.object({ - TestSiteCode: z.string().min(1, "Required"), - TestSiteName: z.string().min(1, "Required"), - Factor: z.string().optional(), - Unit2: z.string().optional(), - Decimal: z.preprocess((val) => { - if (val === "" || val === null || val === undefined) return undefined; - return Number(val); - }, - z.number({invalid_type_error: "Must be a number"}).min(0, "Min 0").max(7, "Max 7").optional() - ), -}).superRefine((data, ctx) => { - if (data.Factor && !data.Unit2) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: "Required", - path: ["Unit2"], - }); - } -}); +export const testSchema = z + .object({ + TestSiteCode: z.string().min(1, 'Required'), + TestSiteName: z.string().min(1, 'Required'), + Factor: z.string().optional(), + Unit2: z.string().optional(), + Decimal: z.preprocess( + (val) => { + if (val === '' || val === null || val === undefined) return undefined; + return Number(val); + }, + z + .number({ invalid_type_error: 'Must be a number' }) + .min(0, 'Min 0') + .max(7, 'Max 7') + .optional() + ) + }) + .superRefine((data, ctx) => { + if (data.Factor && !data.Unit2) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: 'Required', + path: ['Unit2'] + }); + } + }); -export const testCalSchema = z.object({ - FormulaInput: z.array(z.string()).min(1, "Required"), - FormulaCode: z.string().optional(), -}).superRefine((data, ctx) => { - if (data.FormulaInput.length === 0) return; +export const testCalSchema = z + .object({ + FormulaInput: z + .array( + z.object({ + value: z.string(), + level: z.preprocess((val) => (val ? Number(val) : 0), z.number()) + }) + ) + .min(1, 'Required'), + FormulaCode: z.string().optional() + }) + .superRefine((data, ctx) => { + if (data.FormulaInput.length === 0) return; - const hasExactKeyword = (input, keyword) => { - const regex = new RegExp(`\\b${keyword}\\b`, 'i'); - return regex.test(input); - }; + const hasExactKeyword = (input, keyword) => { + const regex = new RegExp(`\\b${keyword}\\b`, 'i'); + return regex.test(input); + }; - const invalid = data.FormulaInput.some( - (v) => !hasExactKeyword(data.FormulaCode, v) - ); + const invalid = data.FormulaInput.some((v) => !hasExactKeyword(data.FormulaCode, v.value)); - if (invalid) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: `Formula must contain all selected input parameters:${data.FormulaInput.join(',')}`, - // message: `Formula must contain all selected input parameters:`, - path: ['FormulaCode'] - }); - } -}); + if (invalid) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: `Formula must contain all selected input parameters:${data.FormulaInput.map((f) => f.value).join(',')}`, + path: ['FormulaCode'] + }); + } + }) + .superRefine((data, ctx) => { + const totalLevel = data.FormulaInput.reduce((sum, item) => sum + (item.level || 0), 0); + if (totalLevel > 5) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: `Level must not exceeded 5 (${totalLevel})`, + path: ['FormulaInput'] + }); + } + }); -export const refNumSchema = z.object({ - AgeStart: z.string().optional(), - AgeEnd: z.string().optional(), - Low: z.string().optional(), - High: z.string().optional(), - LowSign: z.string().optional(), - HighSign: z.string().optional(), - NumRefType: z.string().optional() -}) -.superRefine((data, ctx) => { - const start = toDays(data.AgeStart); - const end = toDays(data.AgeEnd); +export const refNumSchema = z + .object({ + AgeStart: z.string().optional(), + AgeEnd: z.string().optional(), + Low: z.string().optional(), + High: z.string().optional(), + LowSign: z.string().optional(), + HighSign: z.string().optional(), + NumRefType: z.string().optional() + }) + .superRefine((data, ctx) => { + const start = toDays(data.AgeStart); + const end = toDays(data.AgeEnd); - // if (start !== null && start > 0 && end !== null && end <= start) { - if (start !== null && end !== null && end <= start) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: "Age End must be greater than Age Start", - path: ["AgeEnd"], - }); - } -}) -.superRefine((data, ctx) => { - // console.log(data.NumRefType); - if (data.NumRefType === "RANGE") { - const low = Number(data.Low); - const high = Number(data.High); - - if ( - data.Low && - data.High && - !Number.isNaN(low) && - !Number.isNaN(high) && - (high <= low) - ) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: "High value must be greater than Low value", - path: ["High"], - }); - } - } - if (data.NumRefType === "THOLD") { - if (data.Low && !data.LowSign) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: "Math sign for Low is required", - path: ["LowSign"], - }); - } - if (data.High && !data.HighSign) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: "Math sign for High is required", - path: ["HighSign"], - }); - } - if ( - data.LowSign && - data.HighSign && - data.LowSign === data.HighSign - ) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: "High sign can't be the same as Low sign", - path: ["HighSign"], - }); - } - } -}) + // if (start !== null && start > 0 && end !== null && end <= start) { + if (start !== null && end !== null && end <= start) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: 'Age End must be greater than Age Start', + path: ['AgeEnd'] + }); + } + }) + .superRefine((data, ctx) => { + // console.log(data.NumRefType); + if (data.NumRefType === 'RANGE') { + const low = Number(data.Low); + const high = Number(data.High); -export const refTxtSchema = z.object({ - AgeStart: z.string().optional(), - AgeEnd: z.string().optional(), -}) -.superRefine((data, ctx) => { - const start = toDays(data.AgeStart); - const end = toDays(data.AgeEnd); + if (data.Low && data.High && !Number.isNaN(low) && !Number.isNaN(high) && high <= low) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: 'High value must be greater than Low value', + path: ['High'] + }); + } + } + if (data.NumRefType === 'THOLD') { + if (data.Low && !data.LowSign) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: 'Math sign for Low is required', + path: ['LowSign'] + }); + } + if (data.High && !data.HighSign) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: 'Math sign for High is required', + path: ['HighSign'] + }); + } + if (data.LowSign && data.HighSign && data.LowSign === data.HighSign) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: "High sign can't be the same as Low sign", + path: ['HighSign'] + }); + } + } + }); - if (start !== null && end !== null && end <= start) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: "Age End must be greater than Age Start", - path: ["AgeEnd"], - }); - } -}) +export const refTxtSchema = z + .object({ + AgeStart: z.string().optional(), + AgeEnd: z.string().optional() + }) + .superRefine((data, ctx) => { + const start = toDays(data.AgeStart); + const end = toDays(data.AgeEnd); -export const testMapSchema = z.object({ - HostID: z.string().optional(), - ClientID: z.string().optional(), -}) -.superRefine((data, ctx) => { - const hostID = data.HostID; - const clientID = data.ClientID; + if (start !== null && end !== null && end <= start) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: 'Age End must be greater than Age Start', + path: ['AgeEnd'] + }); + } + }); - if (hostID && clientID && hostID === clientID) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: "ClientID must be different from HostID", - path: ["ClientID"], - }); - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: "HostID must be different from ClientID", - path: ["HostID"], - }); - } -}) +export const testMapSchema = z + .object({ + HostID: z.string().optional(), + ClientID: z.string().optional() + }) + .superRefine((data, ctx) => { + const hostID = data.HostID; + const clientID = data.ClientID; + + if (hostID && clientID && hostID === clientID) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: 'ClientID must be different from HostID', + path: ['ClientID'] + }); + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: 'HostID must be different from ClientID', + path: ['HostID'] + }); + } + }); export const testInitialForm = { - TestSiteID: "", - SiteID: "", - TestSiteCode: "", - TestSiteName: "", - TestType: "", - Description: "", - DisciplineID: "", - DepartmentID: "", - ResultType: "", - RefType: "", - Vset: "", - Unit1: "", - Factor: "", - Unit2: "", - Decimal: "", - ReqQty: "", - ReqQtyUnit: "", - CollReq: "", - Method: "", - ExpectedTAT: "", - SeqScr: "", - SeqRpt: "", - VisibleScr: "", - VisibleRpt: "", - CountStat: "", - Level: "", + TestSiteID: '', + SiteID: '', + TestSiteCode: '', + TestSiteName: '', + TestType: '', + Description: '', + DisciplineID: '', + DepartmentID: '', + ResultType: '', + RefType: '', + Vset: '', + Unit1: '', + Factor: '', + Unit2: '', + Decimal: '', + ReqQty: '', + ReqQtyUnit: '', + CollReq: '', + Method: '', + ExpectedTAT: '', + SeqScr: '', + SeqRpt: '', + VisibleScr: '', + VisibleRpt: '', + CountStat: '', + Level: '' }; export const testCalInitialForm = { - TestCalID: "", - TestSiteID: "", - FormulaInput: "", - FormulaCode: "" -} + TestCalID: '', + TestSiteID: '', + FormulaInput: [], + FormulaCode: '' +}; export const refNumInitialForm = { - RefNumID: "", - SiteID: "", - TestSiteID: "", - SpcType: "", - Sex: "", - Criteria: "", - AgeStart: "", - AgeEnd: "", - NumRefType: "", - RangeType: "", - LowSign: "", - Low: "", - HighSign: "", - High: "", - Display: "", - Flag: "", - Interpretation: "", - Notes: "", -} + RefNumID: '', + SiteID: '', + TestSiteID: '', + SpcType: '', + Sex: '', + Criteria: '', + AgeStart: '', + AgeEnd: '', + NumRefType: '', + RangeType: '', + LowSign: '', + Low: '', + HighSign: '', + High: '', + Display: '', + Flag: '', + Interpretation: '', + Notes: '' +}; export const refTxtInitialForm = { - RefTxtID: "", - SiteID: "", - TestSiteID: "", - SpcType: "", - Sex: "", - Criteria: "", - AgeStart: "", - AgeEnd: "", - TxtRefType: "", - RefTxt: "", - Flag: "", - Notes: "", + RefTxtID: '', + SiteID: '', + TestSiteID: '', + SpcType: '', + Sex: '', + Criteria: '', + AgeStart: '', + AgeEnd: '', + TxtRefType: '', + RefTxt: '', + Flag: '', + Notes: '' }; export const testMapInitialForm = { - TestMapID: "", - HostType: "", - HostID: "", - HostTestCode: "", - HostTestName: "", - ClientType: "", - ClientID: "", - ClientTestCode: "", - ClientTestName: "", - ConDefID: "", -} + TestMapID: '', + HostType: '', + HostID: '', + HostTestCode: '', + HostTestName: '', + ClientType: '', + ClientID: '', + ClientTestCode: '', + ClientTestName: '', + ConDefID: '' +}; export const testDefaultErrors = { - TestSiteCode: "Required", - TestSiteName: "Required", - Unit2: null, - Decimal: null, + TestSiteCode: 'Required', + TestSiteName: 'Required', + Unit2: null, + Decimal: null }; export const testCalDefaultErrors = { - FormulaInput: "Required", - FormulaCode: null, + FormulaInput: 'Required', + FormulaCode: null }; export const refNumDefaultErrors = { - AgeStart: null, - AgeEnd: null, - Low: null, - High: null, - LowSign: null, - HighSign: null, + AgeStart: null, + AgeEnd: null, + Low: null, + High: null, + LowSign: null, + HighSign: null }; export const refTxtDefaultErrors = { - AgeStart: null, - AgeEnd: null, + AgeStart: null, + AgeEnd: null }; export const testMapDefaultErrors = { - HostID: null, - ClientID: null, -} + HostID: null, + ClientID: null +}; export const testFormFields = [ - { - title: "Basic Information", - rows: [ - { - type: "row", - columns: [ - { - key: "SiteID", - label: "Site ID", - required: false, - type: "select", - optionsEndpoint: `${API.BASE_URL}${API.SITE}`, - valueKey: "SiteID", - labelKey: (item) => `${item.SiteCode} - ${item.SiteName}`, - }, - { - key: "TestSiteCode", - label: "Test Code", - required: true, - type: "text", - validateOn: ["input"] - } - ] - }, - { - type: "row", - columns: [ - { - key: "TestSiteName", - label: "Test Name", - required: true, - type: "text", - validateOn: ["input"] - }, - { - key: "TestType", - label: "Test Type", - required: false, - type: "select", - optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/test_type`, - } - ] - }, - { - type: "row", - columns: [ - { - key: "Description", - label: "Description", - required: false, - type: "textarea", - }, - ] - }, - ] - }, - { - title: "Organizational Assignment", - rows: [ - { - type: "row", - columns: [ - { - key: "DisciplineID", - label: "Discipline", - required: false, - type: "select", - optionsEndpoint: `${API.BASE_URL}${API.DISCIPLINE}`, - valueKey: "DisciplineID", - labelKey: "DisciplineName", - }, - { - key: "DepartmentID", - label: "Department", - required: false, - type: "select", - optionsEndpoint: `${API.BASE_URL}${API.DEPARTMENT}`, - valueKey: "DepartmentID", - labelKey: "DepartmentName", - }, - ] - }, - ] - }, - { - title: "Result Configuration", - rows: [ - { - type: "row", - columns: [ - { - key: "ResultType", - label: "Result Type", - required: false, - type: "select", - optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/result_type`, - }, - { - key: "RefType", - label: "Reference Type", - required: false, - type: "select", - optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/reference_type`, - } - ] - }, - { - type: "row", - columns: [ - { - key: "VSet", - label: "Value Set", - required: false, - type: "select", - optionsEndpoint: `${API.BASE_URL}${API.VALUESET}`, - fullWidth: false, - autoFetch: false - }, - ] - }, - { - type: "row", - columns: [ - { - key: "Unit1", - label: "Unit 1", - required: false, - type: "text", - }, - { - key: "Factor", - label: "Factor", - required: false, - type: "text", - }, - ] - }, - { - type: "row", - columns: [ - { - key: "Unit2", - label: "Unit 2", - required: false, - type: "text", - }, - { - key: "Decimal", - label: "Decimal", - required: false, - type: "number", - validateOn: ["input"] - }, - ] - }, - { - type: "row", - columns: [ - { - key: "ExpectedTAT", - label: "Expected TAT", - required: false, - type: "text", - fullWidth: false - }, - ] - }, - ] - }, - { - title: "Specimen Requirements", - rows: [ - { - type: "row", - columns: [ - { - key: "ReqQty", - label: "Required Quantity", - required: false, - type: "text", - }, - { - key: "CollReq", - label: "Collection Requirement", - required: false, - type: "text", - }, - ] - }, - { - type: "row", - columns: [ - { - key: "ReqQtyUnit", - label: "Quantity Unit", - required: false, - type: "text", - }, - { - key: "Method", - label: "Method", - required: false, - type: "text", - }, - ] - }, - ] - }, - { - title: "Display Settings", - rows: [ - { - type: "row", - columns: [ - { - key: "SeqScr", - label: "Sequence on Screen", - required: false, - type: "text", - }, - { - key: "VisibleScr", - label: "Visible on Screen", - required: false, - type: "text", - }, - ] - }, - { - type: "row", - columns: [ - { - key: "SeqRpt", - label: "Sequence on Report", - required: false, - type: "text", - }, - { - key: "VisibleRpt", - label: "Visible on Report", - required: false, - type: "text", - }, - ] - }, - ] - }, - { - title: "Other Settings", - rows: [ - { - type: "row", - columns: [ - { - key: "CountStat", - label: "Statistic", - required: false, - type: "text", - }, - { - key: "Level", - label: "Level", - required: false, - type: "text", - }, - ] - }, - ] - }, + { + title: 'Basic Information', + rows: [ + { + type: 'row', + columns: [ + { + key: 'SiteID', + label: 'Site ID', + required: false, + type: 'select', + optionsEndpoint: `${API.BASE_URL}${API.SITE}`, + valueKey: 'SiteID', + labelKey: (item) => `${item.SiteCode} - ${item.SiteName}` + }, + { + key: 'TestSiteCode', + label: 'Test Code', + required: true, + type: 'text', + validateOn: ['input'] + } + ] + }, + { + type: 'row', + columns: [ + { + key: 'TestSiteName', + label: 'Test Name', + required: true, + type: 'text', + validateOn: ['input'] + }, + { + key: 'TestType', + label: 'Test Type', + required: false, + type: 'select', + optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/test_type` + } + ] + }, + { + type: 'row', + columns: [ + { + key: 'Description', + label: 'Description', + required: false, + type: 'textarea' + } + ] + } + ] + }, + { + title: 'Organizational Assignment', + rows: [ + { + type: 'row', + columns: [ + { + key: 'DisciplineID', + label: 'Discipline', + required: false, + type: 'select', + optionsEndpoint: `${API.BASE_URL}${API.DISCIPLINE}`, + valueKey: 'DisciplineID', + labelKey: 'DisciplineName' + }, + { + key: 'DepartmentID', + label: 'Department', + required: false, + type: 'select', + optionsEndpoint: `${API.BASE_URL}${API.DEPARTMENT}`, + valueKey: 'DepartmentID', + labelKey: 'DepartmentName' + } + ] + } + ] + }, + { + title: 'Result Configuration', + rows: [ + { + type: 'row', + columns: [ + { + key: 'ResultType', + label: 'Result Type', + required: false, + type: 'select', + optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/result_type` + }, + { + key: 'RefType', + label: 'Reference Type', + required: false, + type: 'select', + optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/reference_type` + } + ] + }, + { + type: 'row', + columns: [ + { + key: 'VSet', + label: 'Value Set', + required: false, + type: 'select', + optionsEndpoint: `${API.BASE_URL}${API.VALUESET}`, + fullWidth: false, + autoFetch: false + } + ] + }, + { + type: 'row', + columns: [ + { + key: 'Unit1', + label: 'Unit 1', + required: false, + type: 'text' + }, + { + key: 'Factor', + label: 'Factor', + required: false, + type: 'text' + } + ] + }, + { + type: 'row', + columns: [ + { + key: 'Unit2', + label: 'Unit 2', + required: false, + type: 'text' + }, + { + key: 'Decimal', + label: 'Decimal', + required: false, + type: 'number', + validateOn: ['input'] + } + ] + }, + { + type: 'row', + columns: [ + { + key: 'ExpectedTAT', + label: 'Expected TAT', + required: false, + type: 'text', + fullWidth: false + } + ] + } + ] + }, + { + title: 'Specimen Requirements', + rows: [ + { + type: 'row', + columns: [ + { + key: 'ReqQty', + label: 'Required Quantity', + required: false, + type: 'text' + }, + { + key: 'CollReq', + label: 'Collection Requirement', + required: false, + type: 'text' + } + ] + }, + { + type: 'row', + columns: [ + { + key: 'ReqQtyUnit', + label: 'Quantity Unit', + required: false, + type: 'text' + }, + { + key: 'Method', + label: 'Method', + required: false, + type: 'text' + } + ] + } + ] + }, + { + title: 'Display Settings', + rows: [ + { + type: 'row', + columns: [ + { + key: 'SeqScr', + label: 'Sequence on Screen', + required: false, + type: 'text' + }, + { + key: 'VisibleScr', + label: 'Visible on Screen', + required: false, + type: 'text' + } + ] + }, + { + type: 'row', + columns: [ + { + key: 'SeqRpt', + label: 'Sequence on Report', + required: false, + type: 'text' + }, + { + key: 'VisibleRpt', + label: 'Visible on Report', + required: false, + type: 'text' + } + ] + } + ] + }, + { + title: 'Other Settings', + rows: [ + { + type: 'row', + columns: [ + { + key: 'CountStat', + label: 'Statistic', + required: false, + type: 'text' + }, + { + key: 'Level', + label: 'Level', + required: false, + type: 'text' + } + ] + } + ] + } ]; export const testCalFormFields = [ - { - rows: [ - { - type: "row", - columns: [ - { - key: "FormulaInput", - label: "Input Parameter", - required: true, - type: "selectmultiple", - optionsEndpoint: `${API.BASE_URL}${API.TEST}`, - valueKey: "TestSiteCode", - labelKey: (item) => `${item.TestSiteCode} - ${item.TestSiteName}`, - validateOn: ["input"] - }, - ] - }, - { - type: "row", - columns: [ - { - key: "FormulaCode", - label: "Formula Code", - required: false, - type: "formulabuilder", - } - ] - }, - ] - }, + { + rows: [ + { + type: 'row', + columns: [ + { + key: 'FormulaInput', + label: 'Input Parameter', + required: true, + type: 'selectmultiple', + optionsEndpoint: `${API.BASE_URL}${API.TEST}`, + valueKey: 'TestSiteCode', + labelKey: (item) => `${item.TestSiteCode} - ${item.TestSiteName}`, + validateOn: ['input'] + } + ] + }, + { + type: 'row', + columns: [ + { + key: 'FormulaCode', + label: 'Formula Code', + required: false, + type: 'formulabuilder' + } + ] + } + ] + } ]; export const refNumFormFields = [ - { - rows: [ - { - type: "row", - columns: [ - { - key: "SiteID", - label: "Site", - required: false, - type: "select", - optionsEndpoint: `${API.BASE_URL}${API.SITE}`, - valueKey: "SiteID", - labelKey: (item) => `${item.SiteCode} - ${item.SiteName}`, - fullWidth: false - }, - ] - } - ] - }, - { - title: "Criteria Definition", - rows: [ - { - type: "row", - columns: [ - { - key: "Sex", - label: "Sex", - required: false, - type: "select", - optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/sex`, - }, - { - key: "SpcType", - label: "Specimen Type", - required: false, - type: "select", - optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/specimen_type`, - }, - ] - }, - { - type: "row", - columns: [ - { - key: "AgeStart", - label: "Age Start", - required: false, - type: "agejoin", - validateOn: ["input"] - }, - { - key: "AgeEnd", - label: "Age End", - required: false, - type: "agejoin", - validateOn: ["input"] - }, - ] - }, - ] - }, - { - title: "Reference Range Configuration", - rows: [ - { - type: "row", - columns: [ - { - 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`, - }, - ] - }, - { - type: "row", - columns: [ - { - key: "LowSign", - label: "Low Sign - Value", - required: false, - type: "signvalue", - txtKey: "Low", - optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/math_sign`, - validateOn: ["input"] - }, - { - key: "HighSign", - label: "High Sign - Value", - required: false, - type: "signvalue", - txtKey: "High", - optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/math_sign`, - validateOn: ["input"] - }, - ] - }, - { - type: "row", - columns: [ - { - key: "Flag", - label: "Flag", - required: false, - type: "text", - }, - { - key: "Interpretation", - label: "Interpretation", - required: false, - type: "text", - }, - ] - }, - { - type: "row", - columns: [ - { - key: "Notes", - label: "Notes", - required: false, - type: "textarea", - }, - ] - }, - ] - }, - // { - // title: "Flag & Interpretation", - // rows: [ - // { - // type: "row", - // columns: [ - // { - // key: "Flag", - // label: "Flag", - // required: false, - // type: "text", - // }, - // { - // key: "Interpretation", - // label: "Interpretation", - // required: false, - // type: "text", - // }, - // ] - // }, - // { - // type: "row", - // columns: [ - // { - // key: "Notes", - // label: "Notes", - // required: false, - // type: "textarea", - // }, - // ] - // }, - // ] - // }, + { + rows: [ + { + type: 'row', + columns: [ + { + key: 'SiteID', + label: 'Site', + required: false, + type: 'select', + optionsEndpoint: `${API.BASE_URL}${API.SITE}`, + valueKey: 'SiteID', + labelKey: (item) => `${item.SiteCode} - ${item.SiteName}`, + fullWidth: false + } + ] + } + ] + }, + { + title: 'Criteria Definition', + rows: [ + { + type: 'row', + columns: [ + { + key: 'Sex', + label: 'Sex', + required: false, + type: 'select', + optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/sex` + }, + { + key: 'SpcType', + label: 'Specimen Type', + required: false, + type: 'select', + optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/specimen_type` + } + ] + }, + { + type: 'row', + columns: [ + { + key: 'AgeStart', + label: 'Age Start', + required: false, + type: 'agejoin', + validateOn: ['input'] + }, + { + key: 'AgeEnd', + label: 'Age End', + required: false, + type: 'agejoin', + validateOn: ['input'] + } + ] + } + ] + }, + { + title: 'Reference Range Configuration', + rows: [ + { + type: 'row', + columns: [ + { + 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` + } + ] + }, + { + type: 'row', + columns: [ + { + key: 'LowSign', + label: 'Low Sign - Value', + required: false, + type: 'signvalue', + txtKey: 'Low', + optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/math_sign`, + validateOn: ['input'] + }, + { + key: 'HighSign', + label: 'High Sign - Value', + required: false, + type: 'signvalue', + txtKey: 'High', + optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/math_sign`, + validateOn: ['input'] + } + ] + }, + { + type: 'row', + columns: [ + { + key: 'Flag', + label: 'Flag', + required: false, + type: 'text' + }, + { + key: 'Interpretation', + label: 'Interpretation', + required: false, + type: 'text' + } + ] + }, + { + type: 'row', + columns: [ + { + key: 'Notes', + label: 'Notes', + required: false, + type: 'textarea' + } + ] + } + ] + } + // { + // title: "Flag & Interpretation", + // rows: [ + // { + // type: "row", + // columns: [ + // { + // key: "Flag", + // label: "Flag", + // required: false, + // type: "text", + // }, + // { + // key: "Interpretation", + // label: "Interpretation", + // required: false, + // type: "text", + // }, + // ] + // }, + // { + // type: "row", + // columns: [ + // { + // key: "Notes", + // label: "Notes", + // required: false, + // type: "textarea", + // }, + // ] + // }, + // ] + // }, ]; export const refTxtFormFields = [ - { - rows: [ - { - type: "row", - columns: [ - { - key: "SiteID", - label: "Site", - required: false, - type: "select", - optionsEndpoint: `${API.BASE_URL}${API.SITE}`, - valueKey: "SiteID", - labelKey: (item) => `${item.SiteCode} - ${item.SiteName}`, - fullWidth: false - }, - ] - } - ] - }, - { - title: "Criteria Definition", - rows: [ - { - type: "row", - columns: [ - { - key: "Sex", - label: "Sex", - required: false, - type: "select", - optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/sex`, - }, - { - key: "SpcType", - label: "Specimen Type", - required: false, - type: "select", - optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/specimen_type`, - }, - ] - }, - { - type: "row", - columns: [ - { - key: "AgeStart", - label: "Age Start", - required: false, - type: "agejoin", - validateOn: ["input"] - }, - { - key: "AgeEnd", - label: "Age End", - required: false, - type: "agejoin", - validateOn: ["input"] - }, - ] - }, - ] - }, - { - title: "Reference Range Configuration", - rows: [ - { - type: "row", - columns: [ - { - key: "TxtRefType", - label: "Reference Type", - required: false, - type: "text", - fullWidth: false - }, - ] - }, - { - type: "row", - columns: [ - { - key: "RefTxt", - label: "Reference Text", - required: false, - type: "textarea", - }, - ] - }, - ] - }, - { - title: "Flag & Notes", - rows: [ - { - type: "row", - columns: [ - { - key: "Flag", - label: "Flag", - required: false, - type: "text", - fullWidth: false - }, - ] - }, - { - type: "row", - columns: [ - { - key: "Notes", - label: "Notes", - required: false, - type: "textarea", - }, - ] - }, - ] - }, + { + rows: [ + { + type: 'row', + columns: [ + { + key: 'SiteID', + label: 'Site', + required: false, + type: 'select', + optionsEndpoint: `${API.BASE_URL}${API.SITE}`, + valueKey: 'SiteID', + labelKey: (item) => `${item.SiteCode} - ${item.SiteName}`, + fullWidth: false + } + ] + } + ] + }, + { + title: 'Criteria Definition', + rows: [ + { + type: 'row', + columns: [ + { + key: 'Sex', + label: 'Sex', + required: false, + type: 'select', + optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/sex` + }, + { + key: 'SpcType', + label: 'Specimen Type', + required: false, + type: 'select', + optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/specimen_type` + } + ] + }, + { + type: 'row', + columns: [ + { + key: 'AgeStart', + label: 'Age Start', + required: false, + type: 'agejoin', + validateOn: ['input'] + }, + { + key: 'AgeEnd', + label: 'Age End', + required: false, + type: 'agejoin', + validateOn: ['input'] + } + ] + } + ] + }, + { + title: 'Reference Range Configuration', + rows: [ + { + type: 'row', + columns: [ + { + key: 'TxtRefType', + label: 'Reference Type', + required: false, + type: 'text', + fullWidth: false + } + ] + }, + { + type: 'row', + columns: [ + { + key: 'RefTxt', + label: 'Reference Text', + required: false, + type: 'textarea' + } + ] + } + ] + }, + { + title: 'Flag & Notes', + rows: [ + { + type: 'row', + columns: [ + { + key: 'Flag', + label: 'Flag', + required: false, + type: 'text', + fullWidth: false + } + ] + }, + { + type: 'row', + columns: [ + { + key: 'Notes', + label: 'Notes', + required: false, + type: 'textarea' + } + ] + } + ] + } ]; export const testMapFormFields = [ - { - title: "Host & Client Information", - rows: [ - { - type: "row", - columns: [ - { - key: "HostType", - label: "Host Type", - required: false, - type: "select", - optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/entity_type`, - }, - { - key: "ClientType", - label: "Client Type", - required: false, - type: "select", - optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/entity_type`, - }, - ] - }, - { - type: "row", - columns: [ - { - key: "HostID", - label: "Host ID", - required: false, - type: "text", - validateOn: ["input"] - }, - { - key: "ClientID", - label: "Client ID", - required: false, - type: "text", - validateOn: ["input"] - } - ] - }, - { - type: "row", - columns: [ - { - key: "HostTestCode", - label: "Host Test Code", - required: false, - type: "text", - }, - { - key: "ClientTestCode", - label: "Client Test Code", - required: false, - type: "text", - } - ] - }, - { - type: "row", - columns: [ - { - key: "HostTestName", - label: "Host Test Name", - required: false, - type: "text", - }, - { - key: "ClientTestName", - label: "Client Test Name", - required: false, - type: "text", - } - ] - }, - { - type: "row", - columns: [ - { - key: "ConDefID", - label: "Container Definition", - required: false, - type: "select", - optionsEndpoint: `${API.BASE_URL}${API.CONTAINER}`, - valueKey: "ConDefID", - labelKey: (item) => `${item.ConCode} - ${item.ConName}`, - fullWidth: false - }, - ] - }, - ] - }, -] + { + title: 'Host & Client Information', + rows: [ + { + type: 'row', + columns: [ + { + key: 'HostType', + label: 'Host Type', + required: false, + type: 'select', + optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/entity_type` + }, + { + key: 'ClientType', + label: 'Client Type', + required: false, + type: 'select', + optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/entity_type` + } + ] + }, + { + type: 'row', + columns: [ + { + key: 'HostID', + label: 'Host ID', + required: false, + type: 'text', + validateOn: ['input'] + }, + { + key: 'ClientID', + label: 'Client ID', + required: false, + type: 'text', + validateOn: ['input'] + } + ] + }, + { + type: 'row', + columns: [ + { + key: 'HostTestCode', + label: 'Host Test Code', + required: false, + type: 'text' + }, + { + key: 'ClientTestCode', + label: 'Client Test Code', + required: false, + type: 'text' + } + ] + }, + { + type: 'row', + columns: [ + { + key: 'HostTestName', + label: 'Host Test Name', + required: false, + type: 'text' + }, + { + key: 'ClientTestName', + label: 'Client Test Name', + required: false, + type: 'text' + } + ] + }, + { + type: 'row', + columns: [ + { + key: 'ConDefID', + label: 'Container Definition', + required: false, + type: 'select', + optionsEndpoint: `${API.BASE_URL}${API.CONTAINER}`, + valueKey: 'ConDefID', + labelKey: (item) => `${item.ConCode} - ${item.ConName}`, + fullWidth: false + } + ] + } + ] + } +]; export function getTestFormActions(handlers) { - return [ - { - Icon: EraserIcon, - label: 'Clear Form', - onClick: handlers.clearForm, - }, - ]; + return [ + { + Icon: EraserIcon, + label: 'Clear Form', + onClick: handlers.clearForm + } + ]; } -export function buildTestPayload({ - mainForm, - calForm, - refForm, - testType -}) { +export function buildTestPayload({ mainForm, calForm, refForm, testType }) { let payload = { ...mainForm }; @@ -995,11 +1006,11 @@ export function buildTestPayload({ ...calForm }; } else if (testType === 'TEST' || 'PARAM') { - payload = { - ...payload, - ...refForm - } - } + payload = { + ...payload, + ...refForm + }; + } return cleanEmptyStrings(payload); -} \ No newline at end of file +} diff --git a/src/lib/components/dictionary/test/page/tabs/calculation.svelte b/src/lib/components/dictionary/test/page/tabs/calculation.svelte index cdae944..077d943 100644 --- a/src/lib/components/dictionary/test/page/tabs/calculation.svelte +++ b/src/lib/components/dictionary/test/page/tabs/calculation.svelte @@ -9,6 +9,7 @@ import DictionaryFormRenderer from '$lib/components/reusable/form/dictionary-form-renderer.svelte'; let props = $props(); + // const formState = props.calFormState; // let options = $state([]); diff --git a/src/lib/components/reusable/form/dictionary-form-renderer.svelte b/src/lib/components/reusable/form/dictionary-form-renderer.svelte index 3ea5d45..c628dd8 100644 --- a/src/lib/components/reusable/form/dictionary-form-renderer.svelte +++ b/src/lib/components/reusable/form/dictionary-form-renderer.svelte @@ -85,9 +85,9 @@ const selected = formState.form.FormulaInput; if (!Array.isArray(selected)) return []; - return selected.map((v) => ({ - value: v, - done: new RegExp(`\\b${v}\\b`, 'i').test(formulaCode) + return selected.map((item) => ({ + value: item.value, + done: new RegExp(`\\b${item.value}\\b`, 'i').test(formulaCode) })); } @@ -347,13 +347,17 @@ {:else if type === 'selectmultiple'} {@const filteredOptions = getFilteredOptions(key)} + {@const currentValues = Array.isArray(formState.form[key]) ? formState.form[key] : []} item.value)} onValueChange={(val) => { - formState.form[key] = val; + const selectedObjects = (formState.selectOptions?.[key] ?? []).filter((opt) => + val.includes(opt.value) + ); + formState.form[key] = selectedObjects; if (validateOn?.includes('input')) { - formState.validateField?.(key, val, false); + formState.validateField?.(key, selectedObjects, false); formState.validateField?.('FormulaCode', expression, false); } }} @@ -367,9 +371,9 @@ }} > - {formState.form[key]?.length + {currentValues.length ? (formState.selectOptions?.[key] ?? []) - .filter((o) => formState.form[key].includes(o.value)) + .filter((o) => currentValues.some((f) => f.value === o.value)) .map((o) => o.label) .join(', ') : 'Choose'} @@ -387,7 +391,7 @@ {#if formState.loadingOptions?.[key]}
Loading...
{:else} - {#if formState.form[key].length > 0} + {#if currentValues.length > 0} {/each}