All files / plainweb/src/admin/database/routes/[table] index.tsx

0% Statements 0/68
0% Branches 0/1
0% Functions 0/1
0% Lines 0/68

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85                                                                                                                                                                         
import type { Column } from "admin/column";
import { config } from "admin/config";
import { AdminLayout, type NavigationItem } from "admin/layout";
import { sql } from "drizzle-orm";
import type { BetterSQLite3Database } from "drizzle-orm/better-sqlite3";
import type { Handler } from "handler";
import { TableRow } from "./components/table-row";
 
export const GET: Handler = async ({ req, res }) => {
  const tableName = req.params.table as string;
  const db = res.locals.database as BetterSQLite3Database<
    Record<string, unknown>
  >;
 
  const columns = db.all<Column>(
    sql`SELECT * from pragma_table_info(${tableName}) LIMIT 100`,
  );
 
  const rows = db.all<Record<string, unknown>>(
    sql`SELECT * FROM ${sql.identifier(tableName)} LIMIT 100`,
  );
 
  const tables = await db
    .select({ name: sql<string>`name` })
    .from(sql`sqlite_master`)
    .where(sql`type=${"table"} AND name NOT LIKE ${"sqlite_%"}`);
 
  const tableCounts: { tableName: string; count: number }[] = [];
  for (const table of tables) {
    const [rowCount] = db.all<{ count: number }>(
      sql`SELECT COUNT(*) as count FROM ${sql.identifier(table.name)}`,
    );
 
    tableCounts.push({ tableName: table.name, count: rowCount?.count ?? 0 });
  }
 
  const subNavigationItems: NavigationItem[] = tableCounts.map(
    ({ tableName, count }) => ({
      href: `${config.adminBasePath}/database/${tableName}`,
      label: (
        <span class="flex justify-between items-center w-full">
          <span safe>{tableName}</span>
          <span class="ml-2 text-xs text-base-content">{count}</span>
        </span>
      ),
    }),
  );
 
  return (
    <AdminLayout
      subNavigation={subNavigationItems}
      active="database"
      path={req.path}
    >
      <div class="overflow-x-auto w-full whitespace-nowrap text-sm max-w-full">
        <table class="font-mono">
          <thead>
            <tr>
              <th />
              {columns.map((column) => (
                <th
                  safe
                  class="border border-neutral px-2 py-1 text-left max-w-64 min-w-32 truncate"
                >
                  {column.name}
                </th>
              ))}
            </tr>
          </thead>
          <tbody hx-target="closest tr" hx-swap="outerHTML">
            {rows.map((row) => (
              <TableRow
                tableName={tableName}
                columns={columns}
                row={row}
                editing={false}
              />
            ))}
          </tbody>
        </table>
      </div>
    </AdminLayout>
  );
};