316 lines
11 KiB
Svelte

<script>
import { useDictionaryForm } from "$lib/components/composable/use-dictionary-form.svelte";
import FormPageContainer from "$lib/components/reusable/form/form-page-container.svelte";
import DictionaryFormRenderer from "$lib/components/reusable/form/dictionary-form-renderer.svelte";
import { toast } from "svelte-sonner";
import ReusableAlertDialog from "$lib/components/reusable/reusable-alert-dialog.svelte";
import { Separator } from "$lib/components/ui/separator/index.js";
import PencilIcon from "@lucide/svelte/icons/pencil";
import Trash2Icon from "@lucide/svelte/icons/trash-2";
import * as Table from "$lib/components/ui/table/index.js";
import { Button } from "$lib/components/ui/button/index.js";
import { untrack } from "svelte";
import { API } from '$lib/config/api';
import { buildTestMapPayload } from "$lib/components/dictionary/testmap/config/testmap-form-config";
let props = $props();
let editingId = $state(null);
let idCounter = $state(0);
let tempMap = $state([]);
const { masterDetail, formFields, formActions, schema } = props.context;
const { formState } = masterDetail;
const helpers = useDictionaryForm(formState);
const handlers = {
clearForm: () => {
formState.reset();
}
};
const actions = formActions(handlers);
let showConfirm = $state(false);
function snapshotForm() {
return untrack(() => {
const f = formState.form;
return {
HostTestCode: f.HostTestCode ?? "",
HostTestName: f.HostTestName ?? "",
ClientTestCode: f.ClientTestCode ?? "",
ClientTestName: f.ClientTestName ?? "",
ConDefID: f.ConDefID ?? "",
};
});
}
function resetForm() {
formState.reset();
editingId = null;
}
function resetTest() {
untrack(() => {
const f = formState.form;
f.HostTestCode = null;
f.HostTestName = null;
f.ClientTestCode = null;
f.ClientTestName = null;
f.ConDefID = null;
});
editingId = null;
}
function handleInsert() {
const row = {
id: ++idCounter,
...snapshotForm()
};
tempMap = [...tempMap, row];
resetTest();
}
async function handleEdit(row) {
editingId = row.id;
untrack(() => {
const f = formState.form;
// 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) {
// masterDetail.formState.selectOption[key] = row.options[key];
// }
// }
});
}
function handleUpdate() {
tempMap = tempMap.map((row) =>
row.id === editingId ? { id: row.id, ...snapshotForm() } : row
);
resetTest();
}
function handleCancelEdit() {
resetTest();
}
function handleRemove(id) {
tempMap = tempMap.filter((row) => row.id !== id);
if (editingId === id) {
resetTest();
}
}
async function handleSave() {
const mainForm = masterDetail.formState.form;
const payload = buildTestMapPayload({
mainForm,
tempMap,
});
console.log(payload)
// const result = await formState.save(masterDetail.mode, payload);
// toast('Test Map Created!');
// masterDetail?.exitForm(true);
}
const primaryAction = $derived({
label: 'Save',
onClick: handleSave,
disabled: helpers.hasErrors || formState.isSaving.current,
loading: formState.isSaving.current
});
const secondaryActions = [];
const mapFormFieldsTransformed = $derived.by(() => {
return formFields.map((group) => ({
...group,
rows: group.rows.map((row) => ({
...row,
columns: row.columns.map((col) => {
if (col.key === 'HostID') {
if (formState.form.HostType === 'SITE') {
console.log('ini jalan kok');
return {
...col,
type: 'select',
optionsEndpoint: `${API.BASE_URL}${API.SITE}`,
valueKey: 'SiteID',
labelKey: (item) => `${item.SiteCode} - ${item.SiteName}`
};
}
return { ...col, type: 'text', optionsEndpoint: undefined };
}
if (col.key === 'ClientID') {
if (formState.form.ClientType === 'SITE') {
return {
...col,
type: 'select',
optionsEndpoint: `${API.BASE_URL}${API.SITE}`,
valueKey: 'SiteID',
labelKey: (item) => `${item.SiteCode} - ${item.SiteName}`
};
}
return { ...col, type: 'text', optionsEndpoint: undefined };
}
if (col.key === 'HostTestCode') {
if (formState.form.HostType === 'SITE' && formState.form.HostID) {
return {
...col,
type: 'select',
optionsEndpoint: `${API.BASE_URL}${API.TEST}?SiteID=${formState.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') {
if (formState.form.ClientType === 'SITE' && formState.form.ClientID) {
return {
...col,
type: 'select',
optionsEndpoint: `${API.BASE_URL}${API.TEST}?SiteID=${formState.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;
return col;
})
}))
}));
});
// $effect(() => {
// if (formState.form.ClientTestCode) {
// formState.form.ClientTestName = 'nyaho';
// }
// })
</script>
<FormPageContainer title="Create Test Map" {primaryAction} {secondaryActions} {actions}>
<DictionaryFormRenderer
{formState}
formFields={mapFormFieldsTransformed}
mode="create"
/>
<div class="flex flex-col gap-4">
<div class="flex gap-2 mt-1 ms-2">
{#if editingId !== null}
<Button size="sm" class="cursor-pointer" onclick={handleUpdate}>
Update
</Button>
<Button size="sm" variant="outline" class="cursor-pointer" onclick={handleCancelEdit}>
Cancel
</Button>
{:else}
<Button size="sm" class="cursor-pointer" onclick={handleInsert}>
Insert
</Button>
{/if}
</div>
<div>
<Separator />
<Table.Root>
<Table.Header>
<Table.Row class="hover:bg-transparent">
<!-- <Table.Head>Host Type</Table.Head>
<Table.Head>Host ID</Table.Head> -->
<Table.Head>Host Test Code</Table.Head>
<Table.Head>Host Test Name</Table.Head>
<!-- <Table.Head>Client Type</Table.Head>
<Table.Head>Client ID</Table.Head> -->
<Table.Head>Client Test Code</Table.Head>
<Table.Head>Client Test Name</Table.Head>
<Table.Head>Container</Table.Head>
<Table.Head class="w-[80px]"></Table.Head>
</Table.Row>
</Table.Header>
<Table.Body>
{#if tempMap.length === 0}
<Table.Row>
<Table.Cell colspan={9} class="text-center text-muted-foreground py-6">
No data. Fill the form above and click Insert.
</Table.Cell>
</Table.Row>
{:else}
{#each tempMap as row (row.id)}
<Table.Row
class="cursor-pointer hover:bg-muted/50"
>
<Table.Cell>{row.HostTestCode}</Table.Cell>
<Table.Cell>{row.HostTestName}</Table.Cell>
<Table.Cell>{row.ClientTestCode}</Table.Cell>
<Table.Cell>{row.ClientTestName}</Table.Cell>
<Table.Cell>{row.ConDefID}</Table.Cell>
<Table.Cell>
<div class="flex gap-1">
<Button
size="icon"
variant="ghost"
class="h-7 w-7 cursor-pointer"
onclick={() => handleEdit(row)}
>
<PencilIcon class="h-3.5 w-3.5" />
</Button>
<Button
size="icon"
variant="ghost"
class="h-7 w-7 cursor-pointer"
onclick={() => handleRemove(row.id)}
>
<Trash2Icon class="h-3.5 w-3.5" />
</Button>
</div>
</Table.Cell>
</Table.Row>
{/each}
{/if}
</Table.Body>
</Table.Root>
</div>
</div>
</FormPageContainer>
<ReusableAlertDialog
bind:open={masterDetail.showExitConfirm}
onConfirm={masterDetail.confirmExit}
/>