used detailview api instead of audit

This commit is contained in:
suryacp23 2026-07-17 17:21:47 +05:30
parent edddb1b696
commit 3492cdbf9e
2 changed files with 18 additions and 45 deletions

View File

@ -6,7 +6,7 @@
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
<meta name="theme-color" content="#0B1B3B" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="Krishna Sales" />
<link rel="apple-touch-icon" href="/apple-touch-icon-180x180.png" />

View File

@ -2,8 +2,7 @@ import { useEffect, useState } from 'react';
import { cn } from '../../lib/cn';
import { formatValue } from '../../lib/format';
import type { ZinoClient } from '../../api/client';
import type { AuditEntry } from '../../api/types';
import { WORKFLOWS, APP_ID } from '../../api/config';
import { APP_ID } from '../../api/config';
import { Card } from '../reusable/Card';
import { Spinner } from '../reusable/Spinner';
import { EmptyState } from '../reusable/EmptyState';
@ -11,7 +10,7 @@ import { EmptyState } from '../reusable/EmptyState';
export interface DetailViewProps {
/** Workflow-bound client (see api/clients.ts). */
client: ZinoClient;
/** detailview template uid (deprecated, using audit endpoint now). */
/** detailview template uid. */
dvUid?: string;
/** Instance to render. */
instanceId: number | string;
@ -23,29 +22,13 @@ export interface DetailViewProps {
columns?: 1 | 2 | 3;
}
/**
* Helper to resolve a human-readable activity name from its UID.
*/
function getActivityName(uid: string): string | undefined {
for (const wf of Object.values(WORKFLOWS)) {
for (const [actName, actDef] of Object.entries(wf.activities)) {
if (actDef.uid === uid) {
return actName
.split('_')
.map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
.join(' ');
}
}
}
return undefined;
}
/**
* Generic Zino detail view. Fetches `GET /app/{id}/view/audit` and
* renders the audit trail as a labeled definition grid.
* Generic Zino detail view. Fetches `GET /app/{id}/view/detailview/{dvUid}` and
* renders the data as a labeled definition grid.
*/
export function DetailView({ client, instanceId, title, columns = 2 }: DetailViewProps) {
const [entries, setEntries] = useState<AuditEntry[]>([]);
export function DetailView({ client, dvUid, instanceId, title, fields, columns = 2 }: DetailViewProps) {
const [data, setData] = useState<Record<string, unknown> | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
@ -55,9 +38,10 @@ export function DetailView({ client, instanceId, title, columns = 2 }: DetailVie
setLoading(true);
setError(null);
try {
const r = await client.audit(instanceId);
if (!dvUid) throw new Error("dvUid is required to fetch detail view data.");
const r = await client.detailView(dvUid, instanceId);
if (live) {
setEntries(r || []);
setData(r.data || {});
}
} catch (e) {
if (live) setError((e as { message?: string })?.message ?? 'Failed to load');
@ -69,7 +53,7 @@ export function DetailView({ client, instanceId, title, columns = 2 }: DetailVie
return () => {
live = false;
};
}, [client, instanceId]);
}, [client, dvUid, instanceId]);
const gridCols = { 1: 'grid-cols-1', 2: 'grid-cols-1 sm:grid-cols-2', 3: 'grid-cols-1 sm:grid-cols-3' }[columns];
@ -91,29 +75,20 @@ export function DetailView({ client, instanceId, title, columns = 2 }: DetailVie
);
}
if (entries.length === 0) {
if (!data || Object.keys(data).length === 0) {
return (
<Card title={title}>
<EmptyState title="No history found" />
<EmptyState title="No details found" />
</Card>
);
}
return (
<div className="flex flex-col gap-4">
{entries.map((entry, i) => {
const actName = getActivityName(entry.activity_id);
const headerTitle = actName || (i === 0 && title ? title : 'Update');
const updatedAt = new Date(entry.created_at).toLocaleString();
return (
<Card
key={entry.id}
title={headerTitle}
action={<span className="text-xs font-medium text-faint">{updatedAt}</span>}
>
<dl className={cn('grid gap-x-6 gap-y-4', gridCols)}>
{Object.entries(entry.data).map(([key, value]) => {
<Card title={title || 'Details'}>
<dl className={cn('grid gap-x-6 gap-y-4', gridCols)}>
{Object.entries(data).map(([key, value]) => {
if (fields && !fields.includes(key)) return null;
const isGridArray =
Array.isArray(value) &&
value.length > 0 &&
@ -213,9 +188,7 @@ export function DetailView({ client, instanceId, title, columns = 2 }: DetailVie
);
})}
</dl>
</Card>
);
})}
</Card>
</div>
);
}