Lists: owner-only database browser/editor for all tables (meta.edit_log audit)
All checks were successful
Deploy production / deploy (push) Successful in 2m33s
All checks were successful
Deploy production / deploy (push) Successful in 2m33s
This commit is contained in:
@@ -17,13 +17,16 @@
|
||||
let tableFilter = $state('');
|
||||
const schemas = $derived.by(() => {
|
||||
const q = tableFilter.trim().toLowerCase();
|
||||
// eslint-disable-next-line svelte/prefer-svelte-reactivity -- local, rebuilt on every derive
|
||||
const groups = new Map<string, typeof data.tables>();
|
||||
for (const t of data.tables) {
|
||||
if (q && !`${t.schema}.${t.name} ${t.displayName}`.toLowerCase().includes(q)) continue;
|
||||
groups.set(t.schema, [...(groups.get(t.schema) ?? []), t]);
|
||||
}
|
||||
// lists first, then alphabetical
|
||||
return [...groups].sort(([a], [b]) => (a === 'lists' ? -1 : b === 'lists' ? 1 : a.localeCompare(b)));
|
||||
return [...groups].sort(([a], [b]) =>
|
||||
a === 'lists' ? -1 : b === 'lists' ? 1 : a.localeCompare(b)
|
||||
);
|
||||
});
|
||||
const totalRows = $derived(data.tables.reduce((n, t) => n + (t.rows ?? 0), 0));
|
||||
const badge = (access: string, relkind: string) =>
|
||||
@@ -31,7 +34,10 @@
|
||||
? { text: 'editable', cls: 'border-emerald-600/40 text-emerald-500' }
|
||||
: access === 'core'
|
||||
? { text: 'app table', cls: 'border-amber-500/40 text-amber-500' }
|
||||
: { text: relkind === 'v' || relkind === 'm' ? 'view' : 'read-only', cls: 'border-[var(--site-border)] text-[var(--site-muted)]' };
|
||||
: {
|
||||
text: relkind === 'v' || relkind === 'm' ? 'view' : 'read-only',
|
||||
cls: 'border-[var(--site-border)] text-[var(--site-muted)]'
|
||||
};
|
||||
let uploadError = $state('');
|
||||
let uploading = $state(false);
|
||||
const uploadPicture: SubmitFunction = async ({ formData, cancel }) => {
|
||||
@@ -162,7 +168,10 @@
|
||||
<div>
|
||||
<h2 class="text-2xl font-semibold tracking-tight">database</h2>
|
||||
<p class="mt-1 text-sm text-[var(--site-muted)]">
|
||||
{data.tables.length} tables in {new Set(data.tables.map((t) => t.schema)).size} schemas, ~{totalRows.toLocaleString('en-GB')} rows. Only you can see this. Lists are editable; app tables are read-only until you unlock them; a new list is a new table.
|
||||
{data.tables.length} tables in {new Set(data.tables.map((t) => t.schema)).size} schemas, ~{totalRows.toLocaleString(
|
||||
'en-GB'
|
||||
)} rows. Only you can see this. Lists are editable; app tables are read-only until you unlock
|
||||
them; a new list is a new table.
|
||||
</p>
|
||||
</div>
|
||||
<input
|
||||
@@ -177,7 +186,9 @@
|
||||
<details open class="border-t border-[var(--site-border)] py-3" id="schema-{schema}">
|
||||
<summary class="cursor-pointer text-lg font-medium">
|
||||
{schema}
|
||||
<span class="ml-2 text-sm font-normal text-[var(--site-muted)]">{tables.length} {tables.length === 1 ? 'table' : 'tables'}</span>
|
||||
<span class="ml-2 text-sm font-normal text-[var(--site-muted)]"
|
||||
>{tables.length} {tables.length === 1 ? 'table' : 'tables'}</span
|
||||
>
|
||||
</summary>
|
||||
<ul class="mt-2 grid gap-x-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{#each tables as t (t.name)}
|
||||
@@ -187,10 +198,14 @@
|
||||
href={resolve('/lists/db/[schema]/[table]', { schema: t.schema, table: t.name })}
|
||||
class="flex items-center gap-2 rounded px-2 py-1.5 hover:bg-[var(--site-hover)]"
|
||||
>
|
||||
<span class="min-w-0 flex-1 truncate" title={t.description ?? t.displayName}>{t.name}</span>
|
||||
<span class="min-w-0 flex-1 truncate" title={t.description ?? t.displayName}
|
||||
>{t.name}</span
|
||||
>
|
||||
<span class={['rounded-full border px-1.5 text-[10px]', b.cls]}>{b.text}</span>
|
||||
<span class="w-16 text-right text-xs text-[var(--site-muted)] tabular-nums">
|
||||
{t.rows === null ? '–' : `${t.approximate ? '~' : ''}${t.rows.toLocaleString('en-GB')}`}
|
||||
{t.rows === null
|
||||
? '–'
|
||||
: `${t.approximate ? '~' : ''}${t.rows.toLocaleString('en-GB')}`}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
Reference in New Issue
Block a user