The table at /files was wider than the viewport on iPhone-class widths (~375 px) — the rightmost column with the Copy and Delete buttons clipped off-screen with no scroll affordance. Wrapping the table in a .table-wrap div with overflow-x: auto lets the table scroll within itself; moving the outer border to the wrapper preserves the desktop visual unchanged. - public/style.css: add .table-wrap rule, move border off table, add min-width: 100% so the table still fills wide viewports. - src/views/file-list.ts: wrap <table> in <div class="table-wrap">. - tests/integration/pages.test.ts: assert rendered HTML contains class="table-wrap".
45 lines
1.5 KiB
TypeScript
45 lines
1.5 KiB
TypeScript
import { layout, escHtml } from './layout.ts';
|
|
import type { FileRow } from '../db/files.ts';
|
|
|
|
export function fileListPage(files: FileRow[], baseUrl: string): string {
|
|
const rows = files.length === 0
|
|
? '<tr><td colspan="5">No files yet. <a href="/upload">Upload one.</a></td></tr>'
|
|
: files.map((f) => {
|
|
const shareUrl = `${baseUrl}/f/${escHtml(f.id)}`;
|
|
return `
|
|
<tr>
|
|
<td><a href="/f/${escHtml(f.id)}">${escHtml(f.original_name)}</a></td>
|
|
<td>${escHtml(f.mime_type)}</td>
|
|
<td>${formatBytes(f.size)}</td>
|
|
<td>${escHtml(f.created_at)}</td>
|
|
<td>
|
|
<button class="copy-link" onclick="navigator.clipboard.writeText('${shareUrl}')">Copy link</button>
|
|
<form method="POST" action="/files/${escHtml(f.id)}/delete" style="display:inline">
|
|
<button type="submit" class="danger">Delete</button>
|
|
</form>
|
|
</td>
|
|
</tr>`;
|
|
}).join('');
|
|
|
|
return layout('My files', `
|
|
<h1>My files</h1>
|
|
<p><a href="/upload">Upload new file</a></p>
|
|
<div class="table-wrap">
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th><th>Type</th><th>Size</th><th>Uploaded</th><th></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>${rows}</tbody>
|
|
</table>
|
|
</div>
|
|
`, { authed: true });
|
|
}
|
|
|
|
function formatBytes(bytes: number): string {
|
|
if (bytes < 1024) return `${bytes} B`;
|
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
}
|