Change voltage to multiselect on device create and edit forms

Multiple voltages are stored as comma-separated string (e.g. "110V, 220V").
Edit form pre-selects existing values by parsing the stored string.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-07 11:10:04 +07:00
parent adcc8df7cd
commit 3ceabf4e9e
4 changed files with 15 additions and 10 deletions
@@ -43,6 +43,7 @@ export const load: PageServerLoad = async ({ params }) => {
export const actions: Actions = { export const actions: Actions = {
default: async ({ request, params }) => { default: async ({ request, params }) => {
const formData = await request.formData(); const formData = await request.formData();
const voltages = formData.getAll('voltage') as string[];
const raw = Object.fromEntries(formData); const raw = Object.fromEntries(formData);
const result = deviceSchema.safeParse(raw); const result = deviceSchema.safeParse(raw);
@@ -53,6 +54,7 @@ export const actions: Actions = {
const data = result.data; const data = result.data;
const year = typeof data.year === 'number' ? data.year : null; const year = typeof data.year === 'number' ? data.year : null;
const locationId = data.locationId || null; const locationId = data.locationId || null;
const voltage = voltages.length > 0 ? voltages.join(', ') : null;
await db await db
.update(devices) .update(devices)
@@ -64,7 +66,7 @@ export const actions: Actions = {
serialNumber: data.serialNumber || null, serialNumber: data.serialNumber || null,
year, year,
condition: data.condition, condition: data.condition,
voltage: data.voltage || null, voltage,
frequency: data.frequency || null, frequency: data.frequency || null,
origin: data.origin || null, origin: data.origin || null,
faultDescription: data.faultDescription || null, faultDescription: data.faultDescription || null,
@@ -10,6 +10,7 @@
let category = $state(form?.values?.category ?? d.category); let category = $state(form?.values?.category ?? d.category);
let brand = $state(String(form?.values?.brand ?? d.brand ?? '')); let brand = $state(String(form?.values?.brand ?? d.brand ?? ''));
let model = $state(String(form?.values?.model ?? d.model ?? '')); let model = $state(String(form?.values?.model ?? d.model ?? ''));
const existingVoltages = (d.voltage ?? '').split(',').map((v: string) => v.trim()).filter(Boolean);
</script> </script>
<svelte:head> <svelte:head>
@@ -87,13 +88,13 @@
</div> </div>
<div> <div>
<label for="voltage" class="mb-1 block text-sm font-medium text-gray-700 dark:text-gray-300">Voltage</label> <label for="voltage" class="mb-1 block text-sm font-medium text-gray-700 dark:text-gray-300">Voltage</label>
<select id="voltage" name="voltage" <select id="voltage" name="voltage" multiple size="4"
class="w-full rounded-md border border-gray-300 px-3 py-2 text-sm dark:border-gray-600 dark:bg-gray-700 dark:text-white"> class="w-full rounded-md border border-gray-300 px-3 py-1 text-sm dark:border-gray-600 dark:bg-gray-700 dark:text-white">
<option value=""></option>
{#each VOLTAGE_OPTIONS as v} {#each VOLTAGE_OPTIONS as v}
<option value={v} selected={v === (form?.values?.voltage ?? d.voltage)}>{v}</option> <option value={v} selected={existingVoltages.includes(v)}>{v}</option>
{/each} {/each}
</select> </select>
<p class="mt-0.5 text-xs text-gray-400 dark:text-gray-500">Ctrl+click for multiple</p>
</div> </div>
<div> <div>
<label for="frequency" class="mb-1 block text-sm font-medium text-gray-700 dark:text-gray-300">Frequency</label> <label for="frequency" class="mb-1 block text-sm font-medium text-gray-700 dark:text-gray-300">Frequency</label>
+3 -1
View File
@@ -34,6 +34,7 @@ export const load: PageServerLoad = async () => {
export const actions: Actions = { export const actions: Actions = {
default: async ({ request }) => { default: async ({ request }) => {
const formData = await request.formData(); const formData = await request.formData();
const voltages = formData.getAll('voltage') as string[];
const raw = Object.fromEntries(formData); const raw = Object.fromEntries(formData);
const result = deviceSchema.safeParse(raw); const result = deviceSchema.safeParse(raw);
@@ -44,6 +45,7 @@ export const actions: Actions = {
const data = result.data; const data = result.data;
const year = typeof data.year === 'number' ? data.year : null; const year = typeof data.year === 'number' ? data.year : null;
const locationId = data.locationId || null; const locationId = data.locationId || null;
const voltage = voltages.length > 0 ? voltages.join(', ') : null;
const [device] = await db const [device] = await db
.insert(devices) .insert(devices)
@@ -55,7 +57,7 @@ export const actions: Actions = {
serialNumber: data.serialNumber || null, serialNumber: data.serialNumber || null,
year, year,
condition: data.condition, condition: data.condition,
voltage: data.voltage || null, voltage,
frequency: data.frequency || null, frequency: data.frequency || null,
origin: data.origin || null, origin: data.origin || null,
initialCondition: data.initialCondition || null, initialCondition: data.initialCondition || null,
+4 -4
View File
@@ -87,13 +87,13 @@
</div> </div>
<div> <div>
<label for="voltage" class="mb-1 block text-sm font-medium text-gray-700 dark:text-gray-300">Voltage</label> <label for="voltage" class="mb-1 block text-sm font-medium text-gray-700 dark:text-gray-300">Voltage</label>
<select id="voltage" name="voltage" <select id="voltage" name="voltage" multiple size="4"
class="w-full rounded-md border border-gray-300 px-3 py-2 text-sm dark:border-gray-600 dark:bg-gray-700 dark:text-white"> class="w-full rounded-md border border-gray-300 px-3 py-1 text-sm dark:border-gray-600 dark:bg-gray-700 dark:text-white">
<option value=""></option>
{#each VOLTAGE_OPTIONS as v} {#each VOLTAGE_OPTIONS as v}
<option value={v} selected={form?.values?.voltage === v}>{v}</option> <option value={v}>{v}</option>
{/each} {/each}
</select> </select>
<p class="mt-0.5 text-xs text-gray-400 dark:text-gray-500">Ctrl+click for multiple</p>
</div> </div>
<div> <div>
<label for="frequency" class="mb-1 block text-sm font-medium text-gray-700 dark:text-gray-300">Frequency</label> <label for="frequency" class="mb-1 block text-sm font-medium text-gray-700 dark:text-gray-300">Frequency</label>