Add product name to audit log ui

This commit is contained in:
2026-03-26 11:59:53 -04:00
parent 23b94d1c48
commit e4f5e2c4dd
2 changed files with 51 additions and 22 deletions

View File

@@ -91,22 +91,22 @@ router.get('/', async (req, res) => {
let paramIndex = 1; let paramIndex = 1;
if (user_id) { if (user_id) {
conditions.push(`user_id = $${paramIndex++}`); conditions.push(`a.user_id = $${paramIndex++}`);
params.push(user_id); params.push(user_id);
} }
if (pid) { if (pid) {
conditions.push(`pid = $${paramIndex++}`); conditions.push(`a.pid = $${paramIndex++}`);
params.push(pid); params.push(pid);
} }
if (action) { if (action) {
conditions.push(`action = $${paramIndex++}`); conditions.push(`a.action = $${paramIndex++}`);
params.push(action); params.push(action);
} }
if (successFilter !== undefined) { if (successFilter !== undefined) {
conditions.push(`success = $${paramIndex++}`); conditions.push(`a.success = $${paramIndex++}`);
params.push(successFilter === 'true'); params.push(successFilter === 'true');
} }
@@ -116,7 +116,7 @@ router.get('/', async (req, res) => {
// Get total count // Get total count
const countResult = await pool.query( const countResult = await pool.query(
`SELECT COUNT(*) FROM product_editor_audit_log ${whereClause}`, `SELECT COUNT(*) FROM product_editor_audit_log a ${whereClause}`,
params params
); );
@@ -124,19 +124,21 @@ router.get('/', async (req, res) => {
const dataParams = [...params, parseInt(limit, 10), parseInt(offset, 10)]; const dataParams = [...params, parseInt(limit, 10), parseInt(offset, 10)];
const result = await pool.query(` const result = await pool.query(`
SELECT SELECT
id, a.id,
user_id, a.user_id,
username, a.username,
pid, a.pid,
action, p.title AS product_name,
target_endpoint, a.action,
success, a.target_endpoint,
error_message, a.success,
duration_ms, a.error_message,
created_at a.duration_ms,
FROM product_editor_audit_log a.created_at
FROM product_editor_audit_log a
LEFT JOIN products p ON p.pid = a.pid
${whereClause} ${whereClause}
ORDER BY created_at DESC ORDER BY a.created_at DESC
LIMIT $${paramIndex++} OFFSET $${paramIndex++} LIMIT $${paramIndex++} OFFSET $${paramIndex++}
`, dataParams); `, dataParams);
@@ -163,7 +165,7 @@ router.get('/:id', async (req, res) => {
} }
const result = await pool.query( const result = await pool.query(
'SELECT * FROM product_editor_audit_log WHERE id = $1', 'SELECT a.*, p.title AS product_name FROM product_editor_audit_log a LEFT JOIN products p ON p.pid = a.pid WHERE a.id = $1',
[id] [id]
); );

View File

@@ -26,6 +26,7 @@ interface AuditEntry {
errored_count?: number; errored_count?: number;
// Editor-specific // Editor-specific
pid?: number; pid?: number;
product_name?: string | null;
action?: string; action?: string;
} }
@@ -323,7 +324,7 @@ function EditorTable({ entries, onView }: { entries: AuditEntry[]; onView: (id:
<TableRow> <TableRow>
<TableHead className="w-[140px]">Time</TableHead> <TableHead className="w-[140px]">Time</TableHead>
<TableHead>User</TableHead> <TableHead>User</TableHead>
<TableHead>PID</TableHead> <TableHead>Product</TableHead>
<TableHead>Action</TableHead> <TableHead>Action</TableHead>
<TableHead>Status</TableHead> <TableHead>Status</TableHead>
<TableHead>Duration</TableHead> <TableHead>Duration</TableHead>
@@ -335,7 +336,21 @@ function EditorTable({ entries, onView }: { entries: AuditEntry[]; onView: (id:
<TableRow key={e.id}> <TableRow key={e.id}>
<TableCell className="text-xs text-muted-foreground">{formatDate(e.created_at)}</TableCell> <TableCell className="text-xs text-muted-foreground">{formatDate(e.created_at)}</TableCell>
<TableCell>{e.username ?? `#${e.user_id}`}</TableCell> <TableCell>{e.username ?? `#${e.user_id}`}</TableCell>
<TableCell className="font-mono text-sm">{e.pid}</TableCell> <TableCell>
<div className="flex flex-col">
<a
href={`https://backend.acherryontop.com/product/${e.pid}`}
target="_blank"
rel="noopener noreferrer"
className="font-mono text-sm hover:underline text-blue-600 dark:text-blue-400"
>
{e.pid}
</a>
{e.product_name && (
<span className="text-xs text-muted-foreground truncate max-w-[200px]">{e.product_name}</span>
)}
</div>
</TableCell>
<TableCell> <TableCell>
<Badge variant="secondary" className="font-normal"> <Badge variant="secondary" className="font-normal">
{ACTION_LABELS[e.action ?? ""] ?? e.action} {ACTION_LABELS[e.action ?? ""] ?? e.action}
@@ -413,8 +428,20 @@ function DetailView({ detail, logType }: { detail: AuditDetail; logType: LogType
{logType === "editor" && ( {logType === "editor" && (
<> <>
<div> <div>
<span className="text-muted-foreground">Product ID</span> <span className="text-muted-foreground">Product</span>
<p className="font-medium font-mono">{detail.pid}</p> <p className="font-medium">
<a
href={`https://backend.acherryontop.com/product/${detail.pid}`}
target="_blank"
rel="noopener noreferrer"
className="font-mono hover:underline text-blue-600 dark:text-blue-400"
>
{detail.pid}
</a>
{detail.product_name && (
<span className="ml-2 font-sans text-muted-foreground">{detail.product_name}</span>
)}
</p>
</div> </div>
<div> <div>
<span className="text-muted-foreground">Action</span> <span className="text-muted-foreground">Action</span>