feat(08-01): wire diff viewer into config history timeline
- Add click handlers to timeline entries to open diff viewer - Render DiffViewer inline above timeline when snapshot selected - Add hover state and cursor-pointer to timeline entries Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,10 @@
|
|||||||
|
import { useState } from 'react'
|
||||||
import { useQuery } from '@tanstack/react-query'
|
import { useQuery } from '@tanstack/react-query'
|
||||||
import { History } from 'lucide-react'
|
import { History } from 'lucide-react'
|
||||||
import { Badge } from '@/components/ui/badge'
|
import { Badge } from '@/components/ui/badge'
|
||||||
import { TableSkeleton } from '@/components/ui/page-skeleton'
|
import { TableSkeleton } from '@/components/ui/page-skeleton'
|
||||||
import { configHistoryApi } from '@/lib/api'
|
import { configHistoryApi } from '@/lib/api'
|
||||||
|
import { DiffViewer } from './DiffViewer'
|
||||||
|
|
||||||
interface ConfigHistorySectionProps {
|
interface ConfigHistorySectionProps {
|
||||||
tenantId: string
|
tenantId: string
|
||||||
@@ -40,6 +42,7 @@ function LineDelta({ added, removed }: { added: number; removed: number }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function ConfigHistorySection({ tenantId, deviceId }: ConfigHistorySectionProps) {
|
export function ConfigHistorySection({ tenantId, deviceId }: ConfigHistorySectionProps) {
|
||||||
|
const [selectedSnapshotId, setSelectedSnapshotId] = useState<string | null>(null)
|
||||||
const { data: changes, isLoading } = useQuery({
|
const { data: changes, isLoading } = useQuery({
|
||||||
queryKey: ['config-history', tenantId, deviceId],
|
queryKey: ['config-history', tenantId, deviceId],
|
||||||
queryFn: () => configHistoryApi.list(tenantId, deviceId),
|
queryFn: () => configHistoryApi.list(tenantId, deviceId),
|
||||||
@@ -53,6 +56,17 @@ export function ConfigHistorySection({ tenantId, deviceId }: ConfigHistorySectio
|
|||||||
<h3 className="text-sm font-medium text-muted-foreground">Configuration History</h3>
|
<h3 className="text-sm font-medium text-muted-foreground">Configuration History</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{selectedSnapshotId && (
|
||||||
|
<div className="mb-3">
|
||||||
|
<DiffViewer
|
||||||
|
tenantId={tenantId}
|
||||||
|
deviceId={deviceId}
|
||||||
|
snapshotId={selectedSnapshotId}
|
||||||
|
onClose={() => setSelectedSnapshotId(null)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<TableSkeleton rows={3} />
|
<TableSkeleton rows={3} />
|
||||||
) : !changes || changes.length === 0 ? (
|
) : !changes || changes.length === 0 ? (
|
||||||
@@ -68,7 +82,8 @@ export function ConfigHistorySection({ tenantId, deviceId }: ConfigHistorySectio
|
|||||||
{changes.map((entry) => (
|
{changes.map((entry) => (
|
||||||
<div
|
<div
|
||||||
key={entry.id}
|
key={entry.id}
|
||||||
className="relative flex items-start gap-3 pl-8 pr-3 py-2.5 rounded-lg"
|
className="relative flex items-start gap-3 pl-8 pr-3 py-2.5 rounded-lg cursor-pointer hover:bg-elevated/50 transition-colors"
|
||||||
|
onClick={() => setSelectedSnapshotId(entry.snapshot_id)}
|
||||||
>
|
>
|
||||||
{/* Timeline dot */}
|
{/* Timeline dot */}
|
||||||
<div className="absolute left-2 top-3.5 h-2 w-2 rounded-full border border-border bg-elevated" />
|
<div className="absolute left-2 top-3.5 h-2 w-2 rounded-full border border-border bg-elevated" />
|
||||||
|
|||||||
Reference in New Issue
Block a user