mirror of
https://github.com/faiztyanirh/clqms-shadcn-v1.git
synced 2026-04-26 02:46:32 +07:00
25/03/2026
multiple fix/add : change testdefsite to use isBoolean add toggle components in renderer change payload agestart ageend to days initial edit form
This commit is contained in:
parent
5cab6097a9
commit
1389eac272
@ -112,10 +112,10 @@ export async function create(endpoint, formData) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function update(endpoint, formData) {
|
export async function update(endpoint, formData, id) {
|
||||||
console.log(cleanEmptyStrings(formData));
|
console.log(cleanEmptyStrings(formData));
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`${API.BASE_URL}${endpoint}`, {
|
const res = await fetch(`${API.BASE_URL}${endpoint}/${id}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { useFormState } from "./use-form-state.svelte";
|
|||||||
import { useFormOptions } from "./use-form-option.svelte";
|
import { useFormOptions } from "./use-form-option.svelte";
|
||||||
import { useFormValidation } from "./use-form-validation.svelte";
|
import { useFormValidation } from "./use-form-validation.svelte";
|
||||||
|
|
||||||
export function useForm({schema, initialForm, defaultErrors = {}, mode = 'create', modeOpt = 'default', saveEndpoint = null, editEndpoint = null}) {
|
export function useForm({schema, initialForm, defaultErrors = {}, mode = 'create', modeOpt = 'default', saveEndpoint = null, editEndpoint = null, idKey = null}) {
|
||||||
const state = useFormState(initialForm);
|
const state = useFormState(initialForm);
|
||||||
const val = useFormValidation(schema, state.form, defaultErrors, mode);
|
const val = useFormValidation(schema, state.form, defaultErrors, mode);
|
||||||
const options = useFormOptions(modeOpt);
|
const options = useFormOptions(modeOpt);
|
||||||
@ -13,9 +13,16 @@ export function useForm({schema, initialForm, defaultErrors = {}, mode = 'create
|
|||||||
try {
|
try {
|
||||||
// const payload = { ...state.form };
|
// const payload = { ...state.form };
|
||||||
const payload = customPayload || { ...state.form };
|
const payload = customPayload || { ...state.form };
|
||||||
|
let result;
|
||||||
// const { ProvinceID, CityID, ...rest } = state.form;
|
// const { ProvinceID, CityID, ...rest } = state.form;
|
||||||
// const payload = customPayload || rest;
|
// const payload = customPayload || rest;
|
||||||
const result = currentMode === 'edit' ? await editEndpoint(payload) : await saveEndpoint(payload);
|
// const result = currentMode === 'edit' ? await editEndpoint(payload, idKey) : await saveEndpoint(payload);
|
||||||
|
if (currentMode === 'edit') {
|
||||||
|
const id = payload[idKey];
|
||||||
|
result = await editEndpoint(payload, id);
|
||||||
|
} else {
|
||||||
|
result = await saveEndpoint(payload);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Save failed', error);
|
console.error('Save failed', error);
|
||||||
|
|||||||
@ -13,6 +13,6 @@ export async function createTest(newTestForm) {
|
|||||||
return await create(API.TEST, newTestForm)
|
return await create(API.TEST, newTestForm)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function editTest(editTestForm) {
|
export async function editTest(editTestForm, id) {
|
||||||
return await update(API.TEST, editTestForm)
|
return await update(API.TEST, editTestForm, id)
|
||||||
}
|
}
|
||||||
@ -227,10 +227,11 @@ export const testInitialForm = {
|
|||||||
ExpectedTAT: '',
|
ExpectedTAT: '',
|
||||||
SeqScr: '',
|
SeqScr: '',
|
||||||
SeqRpt: '',
|
SeqRpt: '',
|
||||||
VisibleScr: '',
|
isVisibleScr: 1,
|
||||||
VisibleRpt: '',
|
isVisibleRpt: 1,
|
||||||
CountStat: '',
|
isCountStat: 1,
|
||||||
Level: ''
|
Level: '',
|
||||||
|
isRequestable: 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const testCalInitialForm = {
|
export const testCalInitialForm = {
|
||||||
@ -464,7 +465,7 @@ export const testFormFields = [
|
|||||||
key: 'Factor',
|
key: 'Factor',
|
||||||
label: 'Factor',
|
label: 'Factor',
|
||||||
required: false,
|
required: false,
|
||||||
type: 'text'
|
type: 'number'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -540,7 +541,7 @@ export const testFormFields = [
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Display Settings',
|
title: 'Display & Other Settings',
|
||||||
rows: [
|
rows: [
|
||||||
{
|
{
|
||||||
type: 'row',
|
type: 'row',
|
||||||
@ -552,10 +553,35 @@ export const testFormFields = [
|
|||||||
type: 'text'
|
type: 'text'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'VisibleScr',
|
key: 'SeqRpt',
|
||||||
label: 'Visible on Screen',
|
label: 'Sequence on Report',
|
||||||
required: false,
|
required: false,
|
||||||
type: 'text'
|
type: 'text'
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'row',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
key: 'isVisibleScr',
|
||||||
|
label: 'Visible on Screen',
|
||||||
|
required: false,
|
||||||
|
type: 'toggle',
|
||||||
|
optionsToggle: [
|
||||||
|
{ value: 0, label: 'Disabled' },
|
||||||
|
{ value: 1, label: 'Enabled' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'isVisibleRpt',
|
||||||
|
label: 'Visible on Report',
|
||||||
|
required: false,
|
||||||
|
type: 'toggle',
|
||||||
|
optionsToggle: [
|
||||||
|
{ value: 0, label: 'Disabled' },
|
||||||
|
{ value: 1, label: 'Enabled' },
|
||||||
|
],
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -563,43 +589,30 @@ export const testFormFields = [
|
|||||||
type: 'row',
|
type: 'row',
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
key: 'SeqRpt',
|
key: 'isCountStat',
|
||||||
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',
|
label: 'Statistic',
|
||||||
required: false,
|
required: false,
|
||||||
type: 'text'
|
type: 'toggle',
|
||||||
|
optionsToggle: [
|
||||||
|
{ value: 0, label: 'Disabled' },
|
||||||
|
{ value: 1, label: 'Enabled' },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'Level',
|
key: 'isRequestable',
|
||||||
label: 'Level',
|
label: 'Requestable',
|
||||||
required: false,
|
required: false,
|
||||||
type: 'text'
|
type: 'toggle',
|
||||||
}
|
optionsToggle: [
|
||||||
|
{ value: 0, label: 'Disabled' },
|
||||||
|
{ value: 1, label: 'Enabled' },
|
||||||
|
],
|
||||||
|
fullWidth: false
|
||||||
|
},
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const testCalFormFields = [
|
export const testCalFormFields = [
|
||||||
@ -1031,16 +1044,26 @@ export function buildTestPayload({ mainForm, activeFormStates, testType, refNumD
|
|||||||
const state = activeFormStates[key];
|
const state = activeFormStates[key];
|
||||||
|
|
||||||
if (key === 'refNum' && refNumData?.length > 0) {
|
if (key === 'refNum' && refNumData?.length > 0) {
|
||||||
payload[key] = refNumData;
|
// payload[key] = refNumData;
|
||||||
|
payload.refnum = refNumData.map(row => ({
|
||||||
|
...row,
|
||||||
|
AgeStart: toDays(row.AgeStart),
|
||||||
|
AgeEnd: toDays(row.AgeEnd),
|
||||||
|
}))
|
||||||
} else if (key === 'refTxt' && refTxtData?.length > 0) {
|
} else if (key === 'refTxt' && refTxtData?.length > 0) {
|
||||||
payload[key] = refTxtData;
|
// payload[key] = refTxtData;
|
||||||
|
payload.refTxt = refTxtData.map(row => ({
|
||||||
|
...row,
|
||||||
|
AgeStart: toDays(row.AgeStart),
|
||||||
|
AgeEnd: toDays(row.AgeEnd),
|
||||||
|
}))
|
||||||
} else if(key === 'group' && state.form?.Members?.length > 0) {
|
} else if(key === 'group' && state.form?.Members?.length > 0) {
|
||||||
payload[key] = {
|
payload[key] = {
|
||||||
...state.form,
|
...state.form,
|
||||||
Members: state.form?.Members?.map((m) => m.value).filter(Boolean) ?? []
|
Members: state.form?.Members?.map((m) => m.value).filter(Boolean) ?? []
|
||||||
};
|
};
|
||||||
} else if (key === 'map' && mapData?.length > 0) {
|
} else if (key === 'map' && mapData?.length > 0) {
|
||||||
payload[key] = mapData;
|
payload.testMap = mapData;
|
||||||
} else if (key === 'cal') {
|
} else if (key === 'cal') {
|
||||||
payload[key] = {
|
payload[key] = {
|
||||||
...state.form
|
...state.form
|
||||||
|
|||||||
@ -148,10 +148,10 @@
|
|||||||
});
|
});
|
||||||
console.log(payload);
|
console.log(payload);
|
||||||
|
|
||||||
// const result = await formState.save(masterDetail.mode, payload);
|
const result = await formState.save(masterDetail.mode, payload);
|
||||||
|
|
||||||
// toast('Test Created!');
|
toast('Test Created!');
|
||||||
// masterDetail?.exitForm(true);
|
masterDetail?.exitForm(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
const primaryAction = $derived({
|
const primaryAction = $derived({
|
||||||
|
|||||||
@ -3,39 +3,129 @@
|
|||||||
import FormPageContainer from "$lib/components/reusable/form/form-page-container.svelte";
|
import FormPageContainer from "$lib/components/reusable/form/form-page-container.svelte";
|
||||||
import DictionaryFormRenderer from "$lib/components/reusable/form/dictionary-form-renderer.svelte";
|
import DictionaryFormRenderer from "$lib/components/reusable/form/dictionary-form-renderer.svelte";
|
||||||
import { toast } from "svelte-sonner";
|
import { toast } from "svelte-sonner";
|
||||||
import { untrack } from "svelte";
|
|
||||||
import { API } from "$lib/config/api";
|
|
||||||
import ReusableAlertDialog from "$lib/components/reusable/reusable-alert-dialog.svelte";
|
import ReusableAlertDialog from "$lib/components/reusable/reusable-alert-dialog.svelte";
|
||||||
|
import * as Tabs from '$lib/components/ui/tabs/index.js';
|
||||||
|
import { useForm } from '$lib/components/composable/use-form.svelte';
|
||||||
|
import {
|
||||||
|
buildTestPayload,
|
||||||
|
testCalSchema,
|
||||||
|
testCalInitialForm,
|
||||||
|
testCalDefaultErrors,
|
||||||
|
testCalFormFields,
|
||||||
|
refNumSchema,
|
||||||
|
refNumDefaultErrors,
|
||||||
|
refNumInitialForm,
|
||||||
|
refNumFormFields,
|
||||||
|
refTxtSchema,
|
||||||
|
refTxtDefaultErrors,
|
||||||
|
refTxtInitialForm,
|
||||||
|
refTxtFormFields,
|
||||||
|
testMapSchema,
|
||||||
|
testMapInitialForm,
|
||||||
|
testMapDefaultErrors,
|
||||||
|
testMapFormFields,
|
||||||
|
testGroupSchema,
|
||||||
|
testGroupInitialForm,
|
||||||
|
testGroupDefaultErrors,
|
||||||
|
testGroupFormFields
|
||||||
|
} from '$lib/components/dictionary/test/config/test-form-config';
|
||||||
|
import ReusableEmpty from '$lib/components/reusable/reusable-empty.svelte';
|
||||||
|
import RefNum from './tabs/ref-num.svelte';
|
||||||
|
import RefTxt from './tabs/ref-txt.svelte';
|
||||||
|
import Calculation from './tabs/calculation.svelte';
|
||||||
|
import Map from './tabs/map.svelte';
|
||||||
|
import Group from './tabs/group.svelte';
|
||||||
|
import { API } from "$lib/config/api";
|
||||||
|
import { untrack } from "svelte";
|
||||||
|
|
||||||
let props = $props();
|
let props = $props();
|
||||||
|
|
||||||
|
let resetRefNum = $state();
|
||||||
|
let resetRefTxt = $state();
|
||||||
|
let resetMap = $state();
|
||||||
|
let refNumData = $state([]);
|
||||||
|
let refTxtData = $state([]);
|
||||||
|
let mapData = $state([]);
|
||||||
|
|
||||||
const { masterDetail, formFields, formActions, schema, initialForm } = props.context;
|
const { masterDetail, formFields, formActions, schema, initialForm } = props.context;
|
||||||
|
|
||||||
const { formState } = masterDetail;
|
const { formState } = masterDetail;
|
||||||
|
|
||||||
|
$inspect(formState.form)
|
||||||
|
|
||||||
|
const calFormState = useForm({
|
||||||
|
schema: testCalSchema,
|
||||||
|
initialForm: testCalInitialForm,
|
||||||
|
defaultErrors: testCalDefaultErrors
|
||||||
|
});
|
||||||
|
|
||||||
|
const groupFormState = useForm({
|
||||||
|
schema: testGroupSchema,
|
||||||
|
initialForm: testGroupInitialForm,
|
||||||
|
defaultErrors: testGroupDefaultErrors,
|
||||||
|
});
|
||||||
|
|
||||||
|
const refNumState = useForm({
|
||||||
|
schema: refNumSchema,
|
||||||
|
initialForm: refNumInitialForm,
|
||||||
|
defaultErrors: refNumDefaultErrors
|
||||||
|
});
|
||||||
|
|
||||||
|
const refTxtState = useForm({
|
||||||
|
schema: refTxtSchema,
|
||||||
|
initialForm: refTxtInitialForm,
|
||||||
|
defaultErrors: refTxtDefaultErrors
|
||||||
|
});
|
||||||
|
|
||||||
|
const mapFormState = useForm({
|
||||||
|
schema: testMapSchema,
|
||||||
|
initialForm: testMapInitialForm,
|
||||||
|
defaultErrors: testMapDefaultErrors,
|
||||||
|
modeOpt: 'cascade'
|
||||||
|
});
|
||||||
|
|
||||||
|
const activeFormStates = $derived.by(() => {
|
||||||
|
const testType = formState.form.TestType ?? '';
|
||||||
|
const refType = formState.form.RefType ?? '';
|
||||||
|
|
||||||
|
let refState = {};
|
||||||
|
|
||||||
|
if (refType === 'RANGE' || refType === 'THOLD') {
|
||||||
|
refState = { refNum: refNumState };
|
||||||
|
} else if (refType === 'TEXT' || refType === 'VSET') {
|
||||||
|
refState = { refTxt: refTxtState };
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (testType) {
|
||||||
|
case 'TEST':
|
||||||
|
case 'PARAM':
|
||||||
|
return {
|
||||||
|
...refState,
|
||||||
|
map: mapFormState
|
||||||
|
};
|
||||||
|
case 'CALC':
|
||||||
|
return {
|
||||||
|
cal: calFormState,
|
||||||
|
...refState,
|
||||||
|
map: mapFormState
|
||||||
|
};
|
||||||
|
case 'GROUP':
|
||||||
|
return {
|
||||||
|
group: groupFormState
|
||||||
|
}
|
||||||
|
case 'TITLE':
|
||||||
|
default:
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const helpers = useDictionaryForm(formState);
|
const helpers = useDictionaryForm(formState);
|
||||||
|
|
||||||
let showConfirm = $state(false);
|
const allColumns = formFields.flatMap((section) =>
|
||||||
|
section.rows.flatMap((row) => row.columns ?? [])
|
||||||
|
);
|
||||||
|
|
||||||
$effect(() => {
|
let showConfirm = $state(false);
|
||||||
untrack(() => {
|
|
||||||
formFields.forEach(group => {
|
|
||||||
group.rows.forEach(row => {
|
|
||||||
row.columns.forEach(col => {
|
|
||||||
if (col.type === "group") {
|
|
||||||
col.columns.forEach(child => {
|
|
||||||
if (child.type === "select" && child.optionsEndpoint) {
|
|
||||||
formState.fetchOptions(child, formState.form);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if ((col.type === "select") && col.optionsEndpoint) {
|
|
||||||
formState.fetchOptions(col, formState.form);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
async function handleEdit() {
|
async function handleEdit() {
|
||||||
const result = await formState.save(masterDetail.mode);
|
const result = await formState.save(masterDetail.mode);
|
||||||
@ -57,14 +147,265 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
const secondaryActions = [];
|
const secondaryActions = [];
|
||||||
|
|
||||||
|
let availableTabs = $derived.by(() => {
|
||||||
|
const testType = formState?.form?.TestType;
|
||||||
|
|
||||||
|
switch (testType) {
|
||||||
|
case 'TEST':
|
||||||
|
case 'PARAM':
|
||||||
|
return ['definition', 'map', 'reference'];
|
||||||
|
case 'CALC':
|
||||||
|
return ['definition', 'calculation', 'map', 'reference'];
|
||||||
|
case 'GROUP':
|
||||||
|
return ['definition', 'group'];
|
||||||
|
default:
|
||||||
|
return ['definition'];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let disabledResultTypes = $derived.by(() => {
|
||||||
|
const testType = formState?.form?.TestType;
|
||||||
|
|
||||||
|
switch (testType) {
|
||||||
|
case 'TEST':
|
||||||
|
case 'PARAM':
|
||||||
|
return [];
|
||||||
|
case 'CALC':
|
||||||
|
return ['RANGE', 'TEXT', 'VSET', 'NORES'];
|
||||||
|
case 'GROUP':
|
||||||
|
return ['NMRIC', 'RANGE', 'TEXT', 'VSET', 'NORES'];
|
||||||
|
case 'TITLE':
|
||||||
|
return ['NMRIC', 'RANGE', 'TEXT', 'VSET', 'NORES'];
|
||||||
|
default:
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let disabledReferenceTypes = $derived.by(() => {
|
||||||
|
const resultType = formState?.form?.ResultType;
|
||||||
|
|
||||||
|
switch (resultType) {
|
||||||
|
case 'NMRIC':
|
||||||
|
return ['TEXT', 'VSET', 'NOREF'];
|
||||||
|
case 'RANGE':
|
||||||
|
return ['TEXT', 'VSET', 'NOREF'];
|
||||||
|
case 'TEXT':
|
||||||
|
return ['RANGE', 'THOLD', 'VSET', 'NOREF'];
|
||||||
|
case 'VSET':
|
||||||
|
return ['RANGE', 'THOLD', 'TEXT', 'NOREF'];
|
||||||
|
case 'NORES':
|
||||||
|
return ['RANGE', 'THOLD', 'TEXT', 'VSET'];
|
||||||
|
default:
|
||||||
|
return ['RANGE', 'THOLD', 'TEXT', 'VSET', 'NOREF'];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let hiddenFields = $derived.by(() => {
|
||||||
|
const resultType = formState?.form?.ResultType;
|
||||||
|
return resultType !== 'VSET' ? ['VSet'] : [];
|
||||||
|
});
|
||||||
|
|
||||||
|
let refComponent = $derived.by(() => {
|
||||||
|
const refType = formState.form.RefType;
|
||||||
|
if (refType === 'RANGE' || refType === 'THOLD') return 'numeric';
|
||||||
|
if (refType === 'TEXT' || refType === 'VSET') return 'text';
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
const refTxtFormFieldsTransformed = $derived.by(() => {
|
||||||
|
return refTxtFormFields.map((group) => ({
|
||||||
|
...group,
|
||||||
|
rows: group.rows.map((row) => ({
|
||||||
|
...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
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
let activeTab = $state('definition');
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
const mainForm = formState.form;
|
||||||
|
if (mainForm.refnum && Array.isArray(mainForm.refnum)) {
|
||||||
|
refNumData = mainForm.refnum
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
untrack(() => {
|
||||||
|
formFields.forEach(group => {
|
||||||
|
group.rows.forEach(row => {
|
||||||
|
row.columns.forEach(col => {
|
||||||
|
if (col.type === "group") {
|
||||||
|
col.columns.forEach(child => {
|
||||||
|
if (child.type === "select" && child.optionsEndpoint) {
|
||||||
|
formState.fetchOptions(child, formState.form);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if ((col.type === "select") && col.optionsEndpoint) {
|
||||||
|
formState.fetchOptions(col, formState.form);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
if (!availableTabs.includes(activeTab)) {
|
||||||
|
activeTab = availableTabs[0];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
for (const key of hiddenFields) {
|
||||||
|
formState.form[key] = '';
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<FormPageContainer title="Edit Test" {primaryAction} {secondaryActions}>
|
<FormPageContainer title="Edit Test" {primaryAction} {secondaryActions}>
|
||||||
<DictionaryFormRenderer
|
<Tabs.Root bind:value={activeTab} class="w-full h-full">
|
||||||
{formState}
|
<Tabs.List>
|
||||||
formFields={formFields}
|
{#if availableTabs.includes('definition')}
|
||||||
mode="edit"
|
<Tabs.Trigger value="definition">Definition</Tabs.Trigger>
|
||||||
/>
|
{/if}
|
||||||
|
{#if availableTabs.includes('calculation')}
|
||||||
|
<Tabs.Trigger value="calculation">Calculation</Tabs.Trigger>
|
||||||
|
{/if}
|
||||||
|
{#if availableTabs.includes('group')}
|
||||||
|
<Tabs.Trigger value="group">Group</Tabs.Trigger>
|
||||||
|
{/if}
|
||||||
|
{#if availableTabs.includes('reference')}
|
||||||
|
<Tabs.Trigger value="reference">Reference</Tabs.Trigger>
|
||||||
|
{/if}
|
||||||
|
{#if availableTabs.includes('map')}
|
||||||
|
<Tabs.Trigger value="map">Map</Tabs.Trigger>
|
||||||
|
{/if}
|
||||||
|
</Tabs.List>
|
||||||
|
<Tabs.Content value="definition">
|
||||||
|
<DictionaryFormRenderer
|
||||||
|
{formState}
|
||||||
|
formFields={formFields}
|
||||||
|
mode="edit"
|
||||||
|
{hiddenFields}
|
||||||
|
/>
|
||||||
|
</Tabs.Content>
|
||||||
|
<Tabs.Content value="calculation">
|
||||||
|
<Calculation {calFormState} {testCalFormFields} />
|
||||||
|
</Tabs.Content>
|
||||||
|
<Tabs.Content value="group">
|
||||||
|
<Group {groupFormState} {testGroupFormFields} />
|
||||||
|
</Tabs.Content>
|
||||||
|
<Tabs.Content value="map">
|
||||||
|
<Map {mapFormState} testMapFormFields={testMapFormFieldsTransformed} bind:tempMap={mapData} bind:resetMap />
|
||||||
|
</Tabs.Content>
|
||||||
|
<Tabs.Content value="reference">
|
||||||
|
<div class="w-full h-full flex items-start">
|
||||||
|
{#if refComponent === 'numeric'}
|
||||||
|
<RefNum {refNumState} {refNumFormFields} bind:tempNumeric={refNumData} bind:resetRefNum />
|
||||||
|
{:else if refComponent === 'text'}
|
||||||
|
<RefTxt {refTxtState} refTxtFormFields={refTxtFormFieldsTransformed} bind:tempTxt={refTxtData} bind:resetRefTxt />
|
||||||
|
{:else}
|
||||||
|
<div class="h-full w-full flex items-center">
|
||||||
|
<ReusableEmpty desc="Select a Reference Type" />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</Tabs.Content>
|
||||||
|
</Tabs.Root>
|
||||||
</FormPageContainer>
|
</FormPageContainer>
|
||||||
|
|
||||||
<ReusableAlertDialog
|
<ReusableAlertDialog
|
||||||
|
|||||||
@ -113,7 +113,7 @@
|
|||||||
|
|
||||||
resetForm();
|
resetForm();
|
||||||
}
|
}
|
||||||
|
$inspect(props.refNumState.form)
|
||||||
function handleEdit(row) {
|
function handleEdit(row) {
|
||||||
editingId = row.id;
|
editingId = row.id;
|
||||||
|
|
||||||
|
|||||||
@ -19,6 +19,8 @@
|
|||||||
import Trash2Icon from '@lucide/svelte/icons/trash-2';
|
import Trash2Icon from '@lucide/svelte/icons/trash-2';
|
||||||
import PlusIcon from '@lucide/svelte/icons/plus';
|
import PlusIcon from '@lucide/svelte/icons/plus';
|
||||||
import CornerDownLeftIcon from '@lucide/svelte/icons/corner-down-left';
|
import CornerDownLeftIcon from '@lucide/svelte/icons/corner-down-left';
|
||||||
|
import CheckIcon from "@lucide/svelte/icons/check";
|
||||||
|
import XIcon from "@lucide/svelte/icons/x";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
formState,
|
formState,
|
||||||
@ -114,6 +116,7 @@
|
|||||||
type,
|
type,
|
||||||
optionsEndpoint,
|
optionsEndpoint,
|
||||||
options,
|
options,
|
||||||
|
optionsToggle,
|
||||||
validateOn,
|
validateOn,
|
||||||
dependsOn,
|
dependsOn,
|
||||||
endpointParamKey,
|
endpointParamKey,
|
||||||
@ -266,11 +269,17 @@
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onOpenChange={(open) => {
|
onOpenChange={(open) => {
|
||||||
if (open && optionsEndpoint) {
|
if (open) {
|
||||||
formState.fetchOptions?.(
|
if (options && options.length > 0) {
|
||||||
{ key, optionsEndpoint, dependsOn, endpointParamKey, valueKey, labelKey },
|
if (formState.selectOptions) {
|
||||||
formState.form
|
formState.selectOptions[key] = options;
|
||||||
);
|
}
|
||||||
|
} else if (optionsEndpoint) {
|
||||||
|
formState.fetchOptions?.(
|
||||||
|
{ key, optionsEndpoint, dependsOn, endpointParamKey, valueKey, labelKey },
|
||||||
|
formState.form
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@ -806,6 +815,28 @@
|
|||||||
Add Test
|
Add Test
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
{:else if type === "toggle"}
|
||||||
|
{@const toggleOff = optionsToggle?.[0] ?? { value: false, label: 'Off' }}
|
||||||
|
{@const toggleOn = optionsToggle?.[1] ?? { value: true, label: 'On' }}
|
||||||
|
{@const isOn = String(formState.form[key]) === String(toggleOn.value)}
|
||||||
|
<div class="flex items-center w-full">
|
||||||
|
<Toggle
|
||||||
|
aria-label="Toggle"
|
||||||
|
variant="outline"
|
||||||
|
class="w-full transition-all data-[state=on]:text-primary"
|
||||||
|
pressed={isOn}
|
||||||
|
onPressedChange={(pressed) => {
|
||||||
|
formState.form[key] = pressed ? toggleOn.value : toggleOff.value;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{#if isOn}
|
||||||
|
<CheckIcon class="mr-2 h-4 w-4" />
|
||||||
|
{:else}
|
||||||
|
<XIcon class="mr-2 h-4 w-4" />
|
||||||
|
{/if}
|
||||||
|
{isOn ? toggleOn.label : toggleOff.label}
|
||||||
|
</Toggle>
|
||||||
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<Input
|
<Input
|
||||||
type="text"
|
type="text"
|
||||||
|
|||||||
@ -24,5 +24,5 @@ export const API = {
|
|||||||
DISCIPLINE: '/api/organization/discipline',
|
DISCIPLINE: '/api/organization/discipline',
|
||||||
DEPARTMENT: '/api/organization/department',
|
DEPARTMENT: '/api/organization/department',
|
||||||
WORKSTATION: '/api/organization/workstation',
|
WORKSTATION: '/api/organization/workstation',
|
||||||
TEST: '/api/tests',
|
TEST: '/api/test',
|
||||||
};
|
};
|
||||||
|
|||||||
@ -20,6 +20,7 @@
|
|||||||
modeOpt: 'default',
|
modeOpt: 'default',
|
||||||
saveEndpoint: createTest,
|
saveEndpoint: createTest,
|
||||||
editEndpoint: editTest,
|
editEndpoint: editTest,
|
||||||
|
idKey: 'TestSiteID',
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user