forked from 2sys/phonograph
79 lines
1.9 KiB
Svelte
79 lines
1.9 KiB
Svelte
|
|
<svelte:options
|
||
|
|
customElement={{
|
||
|
|
props: {
|
||
|
|
columns: { type: "Array" },
|
||
|
|
subfilter: { type: "String" },
|
||
|
|
},
|
||
|
|
shadow: "none",
|
||
|
|
tag: "table-viewer",
|
||
|
|
}}
|
||
|
|
/>
|
||
|
|
|
||
|
|
<!--
|
||
|
|
@component
|
||
|
|
Top-level web component for the tabular viewing and editing interface for
|
||
|
|
Phonograph portals. Parses HTML attributes, fetches data, and renders the
|
||
|
|
interactive interface implemented by the `<HydratedTableViewer>` Svelte
|
||
|
|
component.
|
||
|
|
-->
|
||
|
|
|
||
|
|
<script lang="ts">
|
||
|
|
import { z } from "zod";
|
||
|
|
|
||
|
|
import { datum_schema } from "../datum.svelte";
|
||
|
|
import { type Row, type FieldInfo, field_info_schema } from "../field.svelte";
|
||
|
|
import HydratedTableViewer from "./hydrated-table-viewer.svelte";
|
||
|
|
|
||
|
|
type Props = {
|
||
|
|
columns?: {
|
||
|
|
name: string;
|
||
|
|
regtype: string;
|
||
|
|
}[];
|
||
|
|
subfilter?: string;
|
||
|
|
};
|
||
|
|
|
||
|
|
let { columns = [], subfilter = "null" }: Props = $props();
|
||
|
|
|
||
|
|
type LazyData = {
|
||
|
|
count: number;
|
||
|
|
rows: Row[];
|
||
|
|
fields: FieldInfo[];
|
||
|
|
};
|
||
|
|
|
||
|
|
let lazy_data = $state<LazyData | undefined>();
|
||
|
|
|
||
|
|
(async function () {
|
||
|
|
const get_data_response_schema = z.object({
|
||
|
|
count: z.number().int(),
|
||
|
|
rows: z.array(
|
||
|
|
z.object({
|
||
|
|
pkey: z.string(),
|
||
|
|
data: z.array(datum_schema),
|
||
|
|
}),
|
||
|
|
),
|
||
|
|
fields: z.array(field_info_schema),
|
||
|
|
});
|
||
|
|
const resp = await fetch(
|
||
|
|
`get-data?subfilter=${encodeURIComponent(subfilter)}`,
|
||
|
|
);
|
||
|
|
const body = get_data_response_schema.parse(await resp.json());
|
||
|
|
lazy_data = {
|
||
|
|
count: body.count,
|
||
|
|
fields: body.fields,
|
||
|
|
rows: body.rows.map(({ data, pkey }) => ({ data, key: pkey })),
|
||
|
|
};
|
||
|
|
})().catch(console.error);
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<div class="table-viewer__layout">
|
||
|
|
{#if lazy_data}
|
||
|
|
<HydratedTableViewer
|
||
|
|
{columns}
|
||
|
|
fields={lazy_data.fields}
|
||
|
|
rows_main={lazy_data.rows}
|
||
|
|
subfilter_active={!!subfilter && subfilter !== "null"}
|
||
|
|
total_count={lazy_data.count}
|
||
|
|
/>
|
||
|
|
{/if}
|
||
|
|
</div>
|