app: lists on meta tables, schema-qualified SQL, typed columns
- lists read/write real lists.* tables via meta.tables/meta.columns and the SECURITY DEFINER meta functions; typed extra columns in the item forms - old numeric list URLs 308-redirect to the slug - include_recurring is boolean, osu accuracy/pp/rate numeric - raw SQL qualified with the new schemas
This commit is contained in:
59
src/lib/components/ListExtraFields.svelte
Normal file
59
src/lib/components/ListExtraFields.svelte
Normal file
@@ -0,0 +1,59 @@
|
||||
<script lang="ts">
|
||||
// Form inputs for a list's own typed columns (meta.columns), posted as `extra:<column>`.
|
||||
import { Input } from '#lib/components/ui/input/index.js';
|
||||
import { Textarea } from '#lib/components/ui/textarea/index.js';
|
||||
import { NativeSelect } from '#lib/components/ui/native-select/index.js';
|
||||
import { Checkbox } from '#lib/components/ui/checkbox/index.js';
|
||||
import type { ExtraValue, ListColumn } from '#lib/server/lists.js';
|
||||
|
||||
let { columns, values = {} }: { columns: ListColumn[]; values?: Record<string, ExtraValue> } =
|
||||
$props();
|
||||
const str = (v: ExtraValue | undefined) => (v === null || v === undefined ? '' : String(v));
|
||||
</script>
|
||||
|
||||
{#each columns as column (column.name)}
|
||||
{@const name = `extra:${column.name}`}
|
||||
{#if column.uiType === 'bool'}
|
||||
<label class="text-sm"
|
||||
><Checkbox {name} value="on" checked={values[column.name] === true} /> {column.label}</label
|
||||
>
|
||||
{:else if column.uiType === 'select' && column.options.length}
|
||||
<label
|
||||
>{column.label}<NativeSelect
|
||||
{name}
|
||||
class="block w-full rounded border p-2"
|
||||
value={str(values[column.name])}
|
||||
>
|
||||
<option value="">—</option>
|
||||
{#each column.options as option (option)}<option value={option}>{option}</option>{/each}
|
||||
</NativeSelect></label
|
||||
>
|
||||
{:else if column.uiType === 'longtext'}
|
||||
<label
|
||||
>{column.label}<Textarea
|
||||
{name}
|
||||
rows={3}
|
||||
maxlength={2000}
|
||||
class="block w-full rounded border p-2"
|
||||
value={str(values[column.name])}
|
||||
/></label
|
||||
>
|
||||
{:else if ['text', 'url', 'image', 'number', 'cents', 'date', 'select'].includes(column.uiType)}
|
||||
<label
|
||||
>{column.label}<Input
|
||||
{name}
|
||||
type={column.uiType === 'number' || column.uiType === 'cents'
|
||||
? 'number'
|
||||
: column.uiType === 'date'
|
||||
? 'date'
|
||||
: column.uiType === 'url' || column.uiType === 'image'
|
||||
? 'url'
|
||||
: 'text'}
|
||||
step={column.uiType === 'number' ? 'any' : undefined}
|
||||
maxlength={column.uiType === 'text' ? 2000 : undefined}
|
||||
class="block w-full rounded border p-2"
|
||||
value={str(values[column.name])}
|
||||
/></label
|
||||
>
|
||||
{/if}
|
||||
{/each}
|
||||
Reference in New Issue
Block a user