From 5817f74ace3332fbd6b868dd2020da9cc13d9a28 Mon Sep 17 00:00:00 2001 From: faiztyanirh Date: Thu, 26 Feb 2026 14:40:36 +0700 Subject: [PATCH] continue dict test map done --- .../test/config/test-form-config.js | 20 +++- .../dictionary/test/page/create-page.svelte | 105 +++++++++++++++--- .../dictionary/test/page/tabs/map.svelte | 105 ++++++++++++++++-- .../form/dictionary-form-renderer.svelte | 84 +++++--------- 4 files changed, 234 insertions(+), 80 deletions(-) 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 ab6e686..3881d77 100644 --- a/src/lib/components/dictionary/test/config/test-form-config.js +++ b/src/lib/components/dictionary/test/config/test-form-config.js @@ -122,7 +122,6 @@ export const refTxtSchema = z.object({ 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, @@ -136,6 +135,23 @@ 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: "", @@ -851,12 +867,14 @@ export const testMapFormFields = [ label: "Host ID", required: false, type: "text", + validateOn: ["input"] }, { key: "ClientID", label: "Client ID", required: false, type: "text", + validateOn: ["input"] } ] }, diff --git a/src/lib/components/dictionary/test/page/create-page.svelte b/src/lib/components/dictionary/test/page/create-page.svelte index c413855..f331302 100644 --- a/src/lib/components/dictionary/test/page/create-page.svelte +++ b/src/lib/components/dictionary/test/page/create-page.svelte @@ -170,25 +170,100 @@ return refTxtFormFields.map(group => ({ ...group, rows: group.rows.map(row => ({ - ...row, - columns: row.columns.map(col => { - if (col.key !== "RefTxt") return col; + ...row, + columns: row.columns.map(col => { + if (col.key !== "RefTxt") return col; + + if (formState.form.ResultType !== "VSET" || !formState.form.VSet) { + return { + ...col, + type: "textarea", + optionsEndpoint: undefined + }; + } - if (formState.form.ResultType !== "VSET" || !formState.form.VSet) { return { ...col, - type: "textarea", - optionsEndpoint: undefined + type: "select", + optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/${formState.form.VSet}`, + fullWidth: false }; - } + }) + })) + })); + }); - return { - ...col, - type: "select", - optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/${formState.form.VSet}`, - fullWidth: false - }; - }) + const testMapFormFieldsTransformed = $derived.by(() => { + return testMapFormFields.map(group => ({ + ...group, + rows: group.rows.map(row => ({ + ...row, + columns: row.columns.map(col => { + + if (col.key === "HostID") { + if (mapFormState.form.HostType === "SITE") { + return { + ...col, + type: "select", + optionsEndpoint: `${API.BASE_URL}${API.SITE}`, + valueKey: "SiteID", + labelKey: (item) => `${item.SiteCode} - ${item.SiteName}`, + }; + } + return col; + } + + if (col.key === "ClientID") { + if (mapFormState.form.ClientType === "SITE") { + return { + ...col, + type: "select", + optionsEndpoint: `${API.BASE_URL}${API.SITE}`, + valueKey: "SiteID", + labelKey: (item) => `${item.SiteCode} - ${item.SiteName}`, + }; + } + return col; + } + + if (col.key === "HostTestCode" || col.key === "HostTestName") { + if (mapFormState.form.HostType === "SITE" && mapFormState.form.HostID) { + return { + ...col, + type: "select", + optionsEndpoint: `${API.BASE_URL}${API.TEST}?SiteID=${mapFormState.form.HostID}`, + valueKey: "TestSiteID", + labelKey: (item) => `${item.TestSiteCode} - ${item.TestSiteName}`, + }; + } + // kalau belum pilih HostID, kembalikan default (misal input biasa) + return { + ...col, + type: "text", + optionsEndpoint: undefined + }; + } + + if (col.key === "ClientTestCode" || col.key === "ClientTestName") { + if (mapFormState.form.ClientType === "SITE" && mapFormState.form.ClientID) { + return { + ...col, + type: "select", + optionsEndpoint: `${API.BASE_URL}${API.TEST}?SiteID=${mapFormState.form.ClientID}`, + valueKey: "TestSiteID", + labelKey: (item) => `${item.TestSiteCode} - ${item.TestSiteName}`, + }; + } + // kalau belum pilih HostID, kembalikan default (misal input biasa) + return { + ...col, + type: "text", + optionsEndpoint: undefined + }; + } + + return col; + }) })) })); }); @@ -343,7 +418,7 @@ group - +
diff --git a/src/lib/components/dictionary/test/page/tabs/map.svelte b/src/lib/components/dictionary/test/page/tabs/map.svelte index 649129c..a7ab7b1 100644 --- a/src/lib/components/dictionary/test/page/tabs/map.svelte +++ b/src/lib/components/dictionary/test/page/tabs/map.svelte @@ -5,6 +5,7 @@ import * as Table from "$lib/components/ui/table/index.js"; import PencilIcon from "@lucide/svelte/icons/pencil"; import Trash2Icon from "@lucide/svelte/icons/trash-2"; + import { untrack } from "svelte"; let { resetMap = $bindable(), ...props } = $props() @@ -15,6 +16,94 @@ resetMap = () => { tempMap = []; }; + + function snapshotForm() { + return untrack(() => { + const f = props.mapFormState.form; + const options = {}; + for (const key in props.mapFormState.selectOptions) { + options[key] = [...props.mapFormState.selectOptions[key]]; + } + return { + HostType: f.HostType ?? "", + HostID: f.HostID ?? "", + HostTestCode: f.HostTestCode ?? "", + HostTestName: f.HostTestName ?? "", + ClientType: f.ClientType ?? "", + ClientID: f.ClientID ?? "", + ClientTestCode: f.ClientTestCode ?? "", + ClientTestName: f.ClientTestName ?? "", + ConDefID: f.ConDefID ?? "", + options: options + }; + }); + } + + function resetForm() { + props.mapFormState.reset?.(); + editingId = null; + } + + function handleInsert() { + const row = { + id: ++idCounter, + ...snapshotForm() + }; + + tempMap = [...tempMap, row]; + + resetForm(); + } + + async function handleEdit(row) { + editingId = row.id; + + untrack(() => { + const f = props.mapFormState.form; + console.log(row); + f.HostType = row.HostType; + f.HostID = row.HostID; + f.HostTestCode = row.HostTestCode; + f.HostTestName = row.HostTestName; + f.ClientType = row.ClientType; + f.ClientID = row.ClientID; + f.ClientTestCode = row.ClientTestCode; + f.ClientTestName = row.ClientTestName; + f.ConDefID = row.ConDefID; + + if (row.options) { + for (const key in row.options) { + props.mapFormState.selectOptions[key] = row.options[key]; + } + } + }); + } + + function handleUpdate() { + tempMap = tempMap.map((row) => + row.id === editingId ? { id: row.id, ...snapshotForm() } : row + ); + resetForm(); + } + + function handleCancelEdit() { + resetForm(); + } + + function handleRemove(id) { + tempMap = tempMap.filter((row) => row.id !== id); + if (editingId === id) resetForm(); + } + + function getLabel(fieldKey, value, rowId) { + const row = tempMap.find(r => r.id === rowId); + if (row && row.options) { + const opts = row.options[fieldKey] ?? []; + const found = opts.find((o) => o.value == value); + return found ? found.label : value; + } + return value; + }
@@ -25,14 +114,14 @@ />
{#if editingId !== null} - - {:else} - {/if} @@ -74,16 +163,17 @@ {row.HostTestCode} {row.HostTestName} {row.ClientType} - {row.ClientID} - {row.ClientTestCode} - {row.ClientTestName} - {row.ConDefID} + {row.ClientID ? getLabel("ClientID", row.ClientID, row.id) : "-"} + {row.ClientTestCode ? getLabel("ClientTestCode", row.ClientTestCode, row.id) : "-"} + {row.ClientTestName ? getLabel("ClientTestName", row.ClientTestName, row.id) : "-"} + {row.ConDefID ? getLabel("ConDefID", row.ConDefID, row.id) : "-"}
@@ -91,6 +181,7 @@ size="icon" variant="ghost" class="h-7 w-7 cursor-pointer" + onclick={() => handleRemove(row.id)} > diff --git a/src/lib/components/reusable/form/dictionary-form-renderer.svelte b/src/lib/components/reusable/form/dictionary-form-renderer.svelte index fadcb5f..b8c99f3 100644 --- a/src/lib/components/reusable/form/dictionary-form-renderer.svelte +++ b/src/lib/components/reusable/form/dictionary-form-renderer.svelte @@ -67,11 +67,6 @@ formState.form[field.key] = field.defaultValue; } } - - // function hasExactKeyword(input, keyword) { - // const regex = new RegExp(`\\b${keyword}\\b`, 'i'); - // return regex.test(input); - // } {#snippet Fieldset({ key, label, required, type, optionsEndpoint, options, validateOn, dependsOn, endpointParamKey, valueKey, labelKey, txtKey })} @@ -81,9 +76,6 @@ {#if required} * {/if} -
@@ -177,6 +169,32 @@ if (key === "RefType") { handleRefTypeChange(val); } + if (key === "HostType") { + formState.form.HostID = ""; + formState.form.HostTestCode = ""; + formState.form.HostTestName = ""; + formState.selectOptions.HostTestCode = []; + formState.selectOptions.HostTestName = []; + } + if (key === "HostID") { + formState.form.HostTestCode = ""; + formState.form.HostTestName = ""; + formState.selectOptions.HostTestCode = []; + formState.selectOptions.HostTestName = []; + } + if (key === "ClientType") { + formState.form.ClientID = ""; + formState.form.ClientTestCode = ""; + formState.form.ClientTestName = ""; + formState.selectOptions.ClientTestCode = []; + formState.selectOptions.ClientTestName = []; + } + if (key === "ClientID") { + formState.form.ClientTestCode = ""; + formState.form.ClientTestName = ""; + formState.selectOptions.ClientTestCode = []; + formState.selectOptions.ClientTestName = []; + } }} onOpenChange={(open) => { if (open && optionsEndpoint) { @@ -305,7 +323,6 @@ { if (validateOn?.includes("input")) { - console.log('object'); // formState.validateField(key, formState.form[key], false); formState.validateField("AgeStart"); formState.validateField("AgeEnd"); @@ -357,19 +374,10 @@ key === 'FormulaCode' ? 'top-20' : 'top-8' }`} > - {#if formState.errors[key] || formState.errors[txtKey]} {formState.errors[key] ?? formState.errors[txtKey]} - {/if}
@@ -420,42 +428,4 @@ {/each}
{/each} -
- - \ No newline at end of file + \ No newline at end of file