Add product name to audit log ui
This commit is contained in:
@@ -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]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user