remove activity timeline from detail view; double-refetch RV after submit
This commit is contained in:
parent
1ec2b02192
commit
7ad50785cc
@ -1,13 +1,13 @@
|
||||
import { useEffect, useState, useCallback } from "react";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { Loader2, CheckCircle2, XCircle, PauseCircle, MessageSquare, Clock } from "lucide-react";
|
||||
import { Loader2, CheckCircle2, XCircle, PauseCircle, MessageSquare } from "lucide-react";
|
||||
import DynamicHeader from "./DynamicHeader";
|
||||
import DashboardStats from "./DashboardStats";
|
||||
import ScreenRenderer from "./ScreenRenderer";
|
||||
import { TableSkeleton } from "./Skeleton";
|
||||
import DetailViewPanel from "./DetailViewPanel";
|
||||
import FormModal from "./FormModal";
|
||||
import { getHeaderConfig, getScreen, getAuditLog, getInstance, type LayoutElement, type NavItem, type AuditEntry } from "../api/viewService";
|
||||
import { getHeaderConfig, getScreen, getInstance, type LayoutElement, type NavItem } from "../api/viewService";
|
||||
import { WORKFLOW_ID, ACTIVITY_IDS, STATE_IDS, SCREEN_UUIDS, RDBMS_RV_SCREEN_UUID, RDBMS_DV_SCREEN_UUID } from "../config";
|
||||
import RecordViewTable from "./RecordViewTable";
|
||||
|
||||
@ -64,7 +64,6 @@ export default function AppShell() {
|
||||
const [refreshKey, setRefreshKey] = useState(0);
|
||||
const [formModal, setFormModal] = useState<{ activityId: string; instanceId: string; title: string } | null>(null);
|
||||
const [instanceState, setInstanceState] = useState<string | null>(null);
|
||||
const [audit, setAudit] = useState<AuditEntry[]>([]);
|
||||
const [sidebarOpen, setSidebarOpen] = useState(true);
|
||||
const [navItems, setNavItems] = useState<NavItem[]>([]);
|
||||
|
||||
@ -92,7 +91,6 @@ export default function AppShell() {
|
||||
setDetailViewId(null);
|
||||
setDetailScreenLayout(null);
|
||||
setInstanceState(null);
|
||||
setAudit([]);
|
||||
} else if (params.instanceId && params.instanceId !== detailInstanceId) {
|
||||
setDetailInstanceId(params.instanceId);
|
||||
const sid = params.screenId ?? activeScreenId;
|
||||
@ -119,18 +117,17 @@ export default function AppShell() {
|
||||
.catch(() => setDetailScreenLayout(null));
|
||||
}, [detailViewId]);
|
||||
|
||||
// Load instance state + audit
|
||||
// Load instance state
|
||||
useEffect(() => {
|
||||
if (!detailInstanceId) return;
|
||||
getInstance(WORKFLOW_ID, detailInstanceId)
|
||||
.then((inst) => setInstanceState(inst.current_state_id))
|
||||
.catch(() => {});
|
||||
getAuditLog(detailInstanceId).then(setAudit).catch(() => setAudit([]));
|
||||
}, [detailInstanceId]);
|
||||
|
||||
const handleNavigate = useCallback((id: string) => {
|
||||
setActiveScreenId(id); setDetailInstanceId(null); setDetailViewId(null);
|
||||
setDetailScreenLayout(null); setInstanceState(null); setAudit([]);
|
||||
setDetailScreenLayout(null); setInstanceState(null);
|
||||
if (RDBMS_SCREENS[id]) setLayout([]);
|
||||
navigate(`/screen/${id}`);
|
||||
}, [navigate]);
|
||||
@ -144,7 +141,7 @@ export default function AppShell() {
|
||||
|
||||
const handleBack = () => {
|
||||
setDetailInstanceId(null); setDetailViewId(null); setDetailScreenLayout(null);
|
||||
setInstanceState(null); setAudit([]);
|
||||
setInstanceState(null);
|
||||
navigate(`/screen/${activeScreenId}`);
|
||||
};
|
||||
|
||||
@ -152,7 +149,6 @@ export default function AppShell() {
|
||||
setFormModal(null);
|
||||
if (detailInstanceId) {
|
||||
const v = detailViewId; setDetailViewId(null); setTimeout(() => setDetailViewId(v), 50);
|
||||
getAuditLog(detailInstanceId).then(setAudit).catch(() => {});
|
||||
}
|
||||
};
|
||||
|
||||
@ -215,64 +211,6 @@ export default function AppShell() {
|
||||
</div>
|
||||
|
||||
{detailScreenLayout ? <ScreenRenderer layout={detailScreenLayout} instanceId={detailInstanceId} /> : <DetailViewPanel viewId={detailViewId} instanceId={detailInstanceId} />}
|
||||
|
||||
{audit.length > 0 && (
|
||||
<div className="bg-white dark:bg-zinc-900 rounded-2xl border border-slate-200/80 dark:border-zinc-700/60 overflow-hidden">
|
||||
<div className="px-5 py-3 border-b border-slate-100 dark:border-zinc-800 flex items-center gap-2.5">
|
||||
<div className="w-6 h-6 rounded-lg flex items-center justify-center"
|
||||
style={{ background: "rgba(124, 58, 237, 0.1)" }}>
|
||||
<Clock size={13} className="text-violet-600 dark:text-violet-400" />
|
||||
</div>
|
||||
<h3 className="text-[13px] font-semibold text-slate-700 dark:text-zinc-200">Activity Timeline</h3>
|
||||
<span className="text-[11px] text-slate-300 dark:text-zinc-600 font-medium">{audit.length} events</span>
|
||||
</div>
|
||||
<div className="px-5 py-4">
|
||||
<div className="relative pl-6">
|
||||
<div className="absolute left-[7px] top-2 bottom-2 w-px"
|
||||
style={{ background: "linear-gradient(to bottom, #7c3aed40, #a855f720, transparent)" }} />
|
||||
<div className="space-y-4">
|
||||
{audit.map((e, i) => {
|
||||
const isFirst = i === 0;
|
||||
const isLast = i === audit.length - 1;
|
||||
return (
|
||||
<div key={e.id} className="flex items-start gap-3 relative">
|
||||
<div
|
||||
className={`absolute -left-6 w-3.5 h-3.5 rounded-full border-2 border-white dark:border-zinc-900 mt-0.5 shadow-sm ${
|
||||
isLast
|
||||
? "ring-2 ring-violet-200 dark:ring-violet-900"
|
||||
: isFirst
|
||||
? ""
|
||||
: ""
|
||||
}`}
|
||||
style={{
|
||||
background: isLast ? "#7c3aed" : isFirst ? "#10b981" : "#d1d5db",
|
||||
boxShadow: isLast ? "0 0 8px rgba(124, 58, 237, 0.5)" : undefined,
|
||||
}}
|
||||
/>
|
||||
<div className="flex-1 py-0.5">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className={`text-[13px] font-medium ${isLast ? "text-violet-700 dark:text-violet-300" : "text-slate-700 dark:text-zinc-200"}`}>
|
||||
{fmtAct(e.activity_id)}
|
||||
</span>
|
||||
{isLast && (
|
||||
<span className="text-[10px] font-semibold px-1.5 py-0.5 rounded-full"
|
||||
style={{ background: "rgba(124, 58, 237, 0.1)", color: "#7c3aed" }}>
|
||||
Latest
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<span className="text-[11px] text-slate-400 dark:text-zinc-500">
|
||||
{new Date(e.created_at).toLocaleString("en-IN", { day: "2-digit", month: "short", hour: "2-digit", minute: "2-digit" })}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : loading ? (
|
||||
<><DashboardStats /><TableSkeleton rows={6} cols={6} /></>
|
||||
@ -287,7 +225,7 @@ export default function AppShell() {
|
||||
} : undefined}
|
||||
/>
|
||||
) : layout.length > 0 ? (
|
||||
<><DashboardStats key={`stats-${activeScreenId}`} /><ScreenRenderer key={`screen-${activeScreenId}-${refreshKey}`} layout={layout} onRowClick={handleRowClick} onRefresh={() => setRefreshKey((k) => k + 1)} /></>
|
||||
<><DashboardStats key={`stats-${activeScreenId}-${refreshKey}`} /><ScreenRenderer key={`screen-${activeScreenId}-${refreshKey}`} layout={layout} onRowClick={handleRowClick} onRefresh={() => { setRefreshKey((k) => k + 1); setTimeout(() => setRefreshKey((k) => k + 1), 2500); }} /></>
|
||||
) : (
|
||||
<div className="text-center py-20 text-sm text-slate-400 dark:text-zinc-600">Select a screen from the navigation</div>
|
||||
)}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user