mirror of
https://github.com/faiztyanirh/clqms-shadcn-v1.git
synced 2026-04-27 20:55:52 +07:00
continue create ordertest page
This commit is contained in:
parent
3f81d45a55
commit
ee04b2e8d5
@ -41,6 +41,8 @@
|
|||||||
const leftGroups = $derived([formFields[0]]);
|
const leftGroups = $derived([formFields[0]]);
|
||||||
const rightGroups = $derived(formFields.slice(1));
|
const rightGroups = $derived(formFields.slice(1));
|
||||||
let selectedTest = $state(null);
|
let selectedTest = $state(null);
|
||||||
|
let selectedTests2 = $state([]);
|
||||||
|
let pendingTests = $state([]);
|
||||||
let selectedCodes = $derived(
|
let selectedCodes = $derived(
|
||||||
new Set((formState.form.Tests ?? []).map(t => t.TestSiteCode))
|
new Set((formState.form.Tests ?? []).map(t => t.TestSiteCode))
|
||||||
);
|
);
|
||||||
@ -68,6 +70,38 @@
|
|||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function toggleTest(test) {
|
||||||
|
const exists = selectedTests2.find(t => t.rawItem.TestSiteID === test.rawItem.TestSiteID);
|
||||||
|
if (exists) {
|
||||||
|
selectedTests2 = selectedTests2.filter(t => t.rawItem.TestSiteID !== test.rawItem.TestSiteID);
|
||||||
|
} else {
|
||||||
|
selectedTests2 = [...selectedTests2, test];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isSelected(test) {
|
||||||
|
return selectedTests2.some(t => t.rawItem.TestSiteID === test.rawItem.TestSiteID);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addSelected() {
|
||||||
|
for (const test of selectedTests2) {
|
||||||
|
const alreadyAdded = pendingTests.some(t => t.rawItem.TestSiteID === test.rawItem.TestSiteID);
|
||||||
|
if (!alreadyAdded) {
|
||||||
|
pendingTests = [...pendingTests, test];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
selectedTests2 = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function isPending(test) {
|
||||||
|
return pendingTests.some(t => t.rawItem.TestSiteID === test.rawItem.TestSiteID);
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeTest2(test) {
|
||||||
|
pendingTests = pendingTests.filter(t => t.rawItem.TestSiteID !== test.rawItem.TestSiteID);
|
||||||
|
selectedTests2 = selectedTests2.filter(t => t.rawItem.TestSiteID !== test.rawItem.TestSiteID);
|
||||||
|
}
|
||||||
|
|
||||||
function getFilteredOptions(key) {
|
function getFilteredOptions(key) {
|
||||||
const query = searchQuery[key] || '';
|
const query = searchQuery[key] || '';
|
||||||
if (!query) return formState.selectOptions?.[key] ?? [];
|
if (!query) return formState.selectOptions?.[key] ?? [];
|
||||||
@ -175,7 +209,7 @@
|
|||||||
Object.entries(testsByDiscipline).filter(([disciplineId]) => disciplineId === selectedDiscipline)
|
Object.entries(testsByDiscipline).filter(([disciplineId]) => disciplineId === selectedDiscipline)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
$inspect(searchedTests)
|
$inspect(pendingTests)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#snippet Fieldset({
|
{#snippet Fieldset({
|
||||||
@ -402,8 +436,10 @@
|
|||||||
{@const filteredOptions = getFilteredOptions(key)}
|
{@const filteredOptions = getFilteredOptions(key)}
|
||||||
<div class="flex flex-1 h-full min-h-0 w-full gap-2">
|
<div class="flex flex-1 h-full min-h-0 w-full gap-2">
|
||||||
<div class="flex flex-1 flex-col gap-2 overflow-hidden min-h-0 h-full w-full">
|
<div class="flex flex-1 flex-col gap-2 overflow-hidden min-h-0 h-full w-full">
|
||||||
<div class="shrink-0 h-18 p-1 flex gap-2 border-b-2 flex flex-col">
|
<div class="shrink-0 h-18 p-1 flex gap-2 flex flex-col">
|
||||||
|
<div class="shrink-0 h-7 border-b-2 flex justify-between items-center">
|
||||||
<p class="text-xs font-medium text-muted-foreground uppercase tracking-wide">Test list</p>
|
<p class="text-xs font-medium text-muted-foreground uppercase tracking-wide">Test list</p>
|
||||||
|
</div>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<Select.Root
|
<Select.Root
|
||||||
type="single"
|
type="single"
|
||||||
@ -434,15 +470,18 @@
|
|||||||
>
|
>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<ChevronDownIcon />
|
<ChevronDownIcon />
|
||||||
<span class="text-sm font-medium">{disciplineName}</span>
|
<span class="text-sm font-medium">{disciplineName ?? 'Unspecified'}</span>
|
||||||
<span class="text-xs text-muted-foreground">{tests.length} tests</span>
|
<span class="text-xs text-muted-foreground">{tests.length} tests</span>
|
||||||
</div>
|
</div>
|
||||||
</Collapsible.Trigger>
|
</Collapsible.Trigger>
|
||||||
<Collapsible.Content>
|
<Collapsible.Content>
|
||||||
<div class="py-1 px-1">
|
<div class="py-1 px-1">
|
||||||
{#each tests as test}
|
{#each tests as test}
|
||||||
<div class="flex items-center gap-3 px-3 py-2 rounded-md transition-colors">
|
<div class="flex items-center gap-3 px-3 py-2 rounded-md transition-colors {isPending(test) ? 'opacity-40 pointer-events-none' : ''}">
|
||||||
<Checkbox />
|
<Checkbox
|
||||||
|
checked={isSelected(test)}
|
||||||
|
onCheckedChange={() => toggleTest(test)}
|
||||||
|
/>
|
||||||
<span class="text-xs font-semibold text-primary w-14 shrink-0">{test.rawItem.TestSiteCode}</span>
|
<span class="text-xs font-semibold text-primary w-14 shrink-0">{test.rawItem.TestSiteCode}</span>
|
||||||
<Label class="text-sm cursor-pointer">{test.rawItem.TestSiteName}</Label>
|
<Label class="text-sm cursor-pointer">{test.rawItem.TestSiteName}</Label>
|
||||||
</div>
|
</div>
|
||||||
@ -453,27 +492,34 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
<div class="shrink-0 p-2 border-t border-b flex items-center justify-between">
|
<div class="shrink-0 p-2 border-t border-b flex items-center justify-between">
|
||||||
<span class="text-sm">0 selected</span>
|
<span class="text-sm">{selectedTests2.length} selected</span>
|
||||||
<Button size="sm" class="px-4 py-2 rounded">Add selected</Button>
|
<Button
|
||||||
|
size="sm"
|
||||||
|
class="px-4 py-2 rounded"
|
||||||
|
onclick={addSelected}
|
||||||
|
disabled={selectedTests2.length === 0}
|
||||||
|
>
|
||||||
|
Add selected
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-1 flex-col overflow-hidden min-h-0 h-full w-1/2 gap-2">
|
<div class="flex flex-1 flex-col overflow-hidden min-h-0 h-full w-1/2 gap-2">
|
||||||
<div class="shrink-0 h-7 border-b-2 flex justify-between items-start">
|
<div class="shrink-0 h-7 border-b-2 flex justify-between items-center">
|
||||||
<p class="text-xs font-medium text-muted-foreground uppercase tracking-wide">Test ordered</p>
|
<p class="text-xs font-medium text-muted-foreground uppercase tracking-wide">Test ordered</p>
|
||||||
<Badge variant="outline">0 test(s)</Badge>
|
<Badge variant="outline">{pendingTests.length} test(s)</Badge>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-col gap-2 p-1 flex-1 min-h-0 overflow-y-auto w-full [scrollbar-width:thin] [&::-webkit-scrollbar]:w-1">
|
<div class="flex flex-col gap-2 p-1 flex-1 min-h-0 overflow-y-auto w-full [scrollbar-width:thin] [&::-webkit-scrollbar]:w-1">
|
||||||
{#each [1,2,3,3] as x }
|
{#each pendingTests as test, index (test.rawItem.TestSiteID) }
|
||||||
<InputGroup.Root class="p-1">
|
<InputGroup.Root class="p-1">
|
||||||
<InputGroup.Addon align="inline-start">
|
<InputGroup.Addon align="inline-start">
|
||||||
1
|
{index + 1}
|
||||||
</InputGroup.Addon>
|
</InputGroup.Addon>
|
||||||
<InputGroup.Addon align="inline-start">
|
<InputGroup.Addon align="inline-start">
|
||||||
CREAD
|
{test.rawItem.TestSiteCode}
|
||||||
</InputGroup.Addon>
|
</InputGroup.Addon>
|
||||||
<InputGroup.Addon align="inline-start">
|
<InputGroup.Addon align="inline-start">
|
||||||
MCU PT. XYZ
|
{test.rawItem.TestSiteName}
|
||||||
</InputGroup.Addon>
|
</InputGroup.Addon>
|
||||||
<InputGroup.Input readonly />
|
<InputGroup.Input readonly />
|
||||||
<InputGroup.Addon align="inline-end">
|
<InputGroup.Addon align="inline-end">
|
||||||
@ -481,6 +527,7 @@
|
|||||||
aria-label="Delete"
|
aria-label="Delete"
|
||||||
title="Delete"
|
title="Delete"
|
||||||
size="icon-xs"
|
size="icon-xs"
|
||||||
|
onclick={() => removeTest2(test)}
|
||||||
>
|
>
|
||||||
<Trash2Icon />
|
<Trash2Icon />
|
||||||
</InputGroup.Button>
|
</InputGroup.Button>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user