- Consolidate fragmented test modal components into unified TestFormModal.svelte - Reorganize reference range components into organized tabs (RefNumTab, RefTxtTab) - Add new tab components: BasicInfoTab, TechDetailsTab, CalcDetailsTab, MappingsTab, GroupMembersTab - Move test-related type definitions to src/lib/types/test.types.ts for better type organization - Delete old component files: TestModal.svelte and 10+ sub-components - Add backup directory for old component preservation - Update AGENTS.md with coding guidelines and project conventions - Update tests.js API client with improved structure - Add documentation for frontend test management architecture
182 lines
5.7 KiB
Svelte
182 lines
5.7 KiB
Svelte
<script>
|
|
import SelectDropdown from '$lib/components/SelectDropdown.svelte';
|
|
import HelpTooltip from '$lib/components/HelpTooltip.svelte';
|
|
|
|
/**
|
|
* @typedef {Object} Props
|
|
* @property {Object} formData - Form data object
|
|
* @property {boolean} canHaveFormula - Whether test can have a formula
|
|
* @property {Array<{value: string, label: string}>} disciplineOptions - Discipline dropdown options
|
|
* @property {Array<{value: string, label: string}>} departmentOptions - Department dropdown options
|
|
* @property {() => void} onsave - Save handler
|
|
*/
|
|
|
|
/** @type {Props} */
|
|
let {
|
|
formData = $bindable({}),
|
|
canHaveFormula = false,
|
|
disciplineOptions = [],
|
|
departmentOptions = [],
|
|
onsave = () => {}
|
|
} = $props();
|
|
|
|
const typeLabels = {
|
|
TEST: 'Test',
|
|
PARAM: 'Parameter',
|
|
CALC: 'Calculated',
|
|
GROUP: 'Panel'
|
|
};
|
|
|
|
function handleSubmit(e) {
|
|
e.preventDefault();
|
|
onsave();
|
|
}
|
|
</script>
|
|
|
|
<form class="space-y-3" onsubmit={handleSubmit}>
|
|
<!-- Test Type Header -->
|
|
<div class="bg-base-200 rounded-lg px-4 py-3 mb-4">
|
|
<span class="text-sm text-gray-500">Test Type</span>
|
|
<div class="font-semibold text-lg">{typeLabels[formData.TestType]}</div>
|
|
</div>
|
|
|
|
<!-- Basic Info -->
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<div class="form-control">
|
|
<label class="label" for="testCode">
|
|
<span class="label-text text-sm font-medium">Test Code</span>
|
|
<span class="label-text-alt text-xs text-error">*</span>
|
|
</label>
|
|
<input
|
|
id="testCode"
|
|
type="text"
|
|
class="input input-sm input-bordered w-full"
|
|
bind:value={formData.TestSiteCode}
|
|
placeholder="e.g., GLU"
|
|
required
|
|
/>
|
|
</div>
|
|
<div class="form-control">
|
|
<label class="label" for="testName">
|
|
<span class="label-text text-sm font-medium">Test Name</span>
|
|
<span class="label-text-alt text-xs text-error">*</span>
|
|
</label>
|
|
<input
|
|
id="testName"
|
|
type="text"
|
|
class="input input-sm input-bordered w-full"
|
|
bind:value={formData.TestSiteName}
|
|
placeholder="e.g., Glucose"
|
|
required
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Discipline and Department -->
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<SelectDropdown
|
|
label="Discipline"
|
|
name="discipline"
|
|
bind:value={formData.DisciplineID}
|
|
options={disciplineOptions}
|
|
placeholder="Select discipline..."
|
|
/>
|
|
<SelectDropdown
|
|
label="Department"
|
|
name="department"
|
|
bind:value={formData.DepartmentID}
|
|
options={departmentOptions}
|
|
placeholder="Select department..."
|
|
/>
|
|
</div>
|
|
|
|
<!-- Type-specific fields -->
|
|
{#if canHaveFormula}
|
|
<div class="grid grid-cols-1 md:grid-cols-1 gap-4">
|
|
<div class="form-control">
|
|
<label class="label" for="formula">
|
|
<span class="label-text text-sm font-medium flex items-center gap-2">
|
|
Formula
|
|
<HelpTooltip
|
|
text="Enter a mathematical formula using test codes (e.g., BUN / Creatinine). Supported operators: +, -, *, /, parentheses."
|
|
title="Formula Help"
|
|
/>
|
|
</span>
|
|
<span class="label-text-alt text-xs text-error">*</span>
|
|
</label>
|
|
<input
|
|
id="formula"
|
|
type="text"
|
|
class="input input-sm input-bordered w-full"
|
|
bind:value={formData.Formula}
|
|
placeholder="e.g., BUN / Creatinine"
|
|
required={canHaveFormula}
|
|
/>
|
|
<span class="label-text-alt text-xs text-gray-500">Use test codes with operators: +, -, *, /</span>
|
|
</div>
|
|
</div>
|
|
{/if}
|
|
|
|
<!-- Description -->
|
|
<div class="form-control">
|
|
<label class="label" for="description">
|
|
<span class="label-text text-sm font-medium">Description</span>
|
|
</label>
|
|
<textarea
|
|
id="description"
|
|
class="textarea textarea-bordered w-full"
|
|
bind:value={formData.Description}
|
|
placeholder="Enter test description..."
|
|
rows="3"
|
|
></textarea>
|
|
</div>
|
|
|
|
<!-- Screen Sequence, Report Sequence, Visibility, and Statistics -->
|
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
|
<div class="form-control">
|
|
<label class="label" for="seqScr">
|
|
<span class="label-text text-sm font-medium">Screen Sequence</span>
|
|
</label>
|
|
<input
|
|
id="seqScr"
|
|
type="number"
|
|
class="input input-sm input-bordered w-full"
|
|
bind:value={formData.SeqScr}
|
|
placeholder="0"
|
|
/>
|
|
</div>
|
|
<div class="form-control">
|
|
<label class="label" for="seqRpt">
|
|
<span class="label-text text-sm font-medium">Report Sequence</span>
|
|
</label>
|
|
<input
|
|
id="seqRpt"
|
|
type="number"
|
|
class="input input-sm input-bordered w-full"
|
|
bind:value={formData.SeqRpt}
|
|
placeholder="0"
|
|
/>
|
|
</div>
|
|
<div class="form-control">
|
|
<span class="label-text text-sm font-medium mb-2 block">Visibility</span>
|
|
<div class="flex gap-4">
|
|
<label class="label cursor-pointer gap-2">
|
|
<input type="checkbox" class="checkbox" bind:checked={formData.VisibleScr} />
|
|
<span class="label-text">Screen</span>
|
|
</label>
|
|
<label class="label cursor-pointer gap-2">
|
|
<input type="checkbox" class="checkbox" bind:checked={formData.VisibleRpt} />
|
|
<span class="label-text">Report</span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="form-control">
|
|
<span class="label-text text-sm font-medium mb-2 block">Statistics</span>
|
|
<label class="label cursor-pointer gap-2">
|
|
<input type="checkbox" class="checkbox" bind:checked={formData.CountStat} />
|
|
<span class="label-text">Count in Statistics</span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</form>
|