-
Notifications
You must be signed in to change notification settings - Fork 97
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature: add screen to view mirror activity
- Loading branch information
Pankaj Bhageria
authored and
Pankaj Bhageria
committed
Nov 8, 2023
1 parent
fb90f2a
commit 6dda1f1
Showing
6 changed files
with
187 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,78 @@ | ||
'use client' | ||
import { Label } from '@/lib/Label'; | ||
import {formatDistance } from 'date-fns' | ||
import { Badge } from '@/lib/Badge'; | ||
import { Icon } from '@/lib/Icon'; | ||
import {Action} from '@/lib/Action'; | ||
import { FlowConnectionConfigs } from '@/grpc_generated/flow'; | ||
import CdcGraph from './cdcGraph' | ||
|
||
type CDCDetailsProps = { | ||
config: FlowConnectionConfigs | undefined; | ||
|
||
|
||
type SyncStatusRow = { | ||
batchId: number; | ||
startTime: Date; | ||
endTime: Date | null; | ||
numRows: number; | ||
}; | ||
|
||
export default function CDCDetails({ config }: CDCDetailsProps) { | ||
if (!config) { | ||
return <div className='text-red-500'>No configuration provided</div>; | ||
} | ||
type props = { | ||
syncs: SyncStatusRow[]; | ||
mirrorConfig: FlowConnectionConfigs | undefined; | ||
}; | ||
function CdcDetails({ syncs,mirrorConfig }:props) { | ||
|
||
let lastSyncedAt = formatDistance(syncs[0]?.startTime, new Date(), { addSuffix: true }) | ||
|
||
let rowsSynced = syncs.reduce((acc, sync) => acc + sync.numRows, 0) | ||
|
||
return ( | ||
<div className='p-4 rounded-md'> | ||
<h2 className='text-xl font-semibold mb-4'>CDC Details</h2> | ||
<div className='overflow-x-auto'> | ||
<table className='min-w-full divide-y divide-gray-300'> | ||
<tbody> | ||
<tr> | ||
<td className='px-4 py-2 font-medium'>Source</td> | ||
<td className='px-4 py-2'>{config.source?.name || '-'}</td> | ||
</tr> | ||
<tr> | ||
<td className='px-4 py-2 font-medium'>Destination</td> | ||
<td className='px-4 py-2'>{config.destination?.name || '-'}</td> | ||
</tr> | ||
<tr> | ||
<td className='px-4 py-2 font-medium'>Flow Job Name</td> | ||
<td className='px-4 py-2'>{config.flowJobName}</td> | ||
</tr> | ||
</tbody> | ||
</table> | ||
<> | ||
<div className='mt-10'> | ||
<div className="flex flex-row"> | ||
<div className="basis-1/4 md:basis-1/3"> | ||
<div><Label variant="subheadline" colorName='lowContrast'>Status</Label></div> | ||
<div><Label variant="body"> | ||
<Badge variant='positive' key={1}> | ||
<Icon name='play_circle' /> | ||
Active | ||
</Badge> | ||
</Label> | ||
</div> | ||
</div> | ||
<div className="basis-1/4 md:basis-1/3"> | ||
<div><Label variant="subheadline" colorName='lowContrast'>Mirror Type</Label></div> | ||
<div><Label variant="body">CDC</Label></div> | ||
</div> | ||
<div className="basis-1/4 md:basis-1/3"> | ||
<div><Label variant="subheadline" colorName='lowContrast'>Source</Label></div> | ||
<div><Action href={"/peers/"+mirrorConfig?.source?.name}>{mirrorConfig?.source?.name}</Action></div> | ||
</div> | ||
<div className="basis-1/4 md:basis-1/3"> | ||
<div><Label variant="subheadline" colorName='lowContrast'>Destination</Label></div> | ||
<div><Action href={"/peers/"+ mirrorConfig?.destination?.name}>{mirrorConfig?.destination?.name}</Action></div> | ||
</div> | ||
</div> | ||
<div className="flex flex-row mt-10"> | ||
<div className="basis-1/4"> | ||
<div><Label variant="subheadline" colorName='lowContrast'>Last Sync</Label></div> | ||
<div><Label variant="body">{lastSyncedAt}</Label></div> | ||
</div> | ||
<div className="basis-1/4"> | ||
<div><Label variant="subheadline" colorName='lowContrast'>Rows synced</Label></div> | ||
<div><Label variant="body">{numberWithCommas(rowsSynced)}</Label></div> | ||
</div> | ||
</div> | ||
</div> | ||
<div className='mt-10'> | ||
<CdcGraph syncs={syncs}/> | ||
</div> | ||
</> | ||
); | ||
} | ||
|
||
function numberWithCommas(x:Number) { | ||
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); | ||
} | ||
|
||
export default CdcDetails |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import { Label } from '@/lib/Label'; | ||
import { useState, useEffect } from 'react'; | ||
import { format } from 'date-fns' | ||
|
||
type SyncStatusRow = { | ||
batchId: number; | ||
startTime: Date; | ||
endTime: Date | null; | ||
numRows: number; | ||
}; | ||
|
||
import aggregateCountsByInterval from './aggregatedCountsByInterval' | ||
|
||
function CdcGraph({syncs}:{syncs:SyncStatusRow[]}) { | ||
|
||
let [aggregateType,setAggregateType] = useState('hour'); | ||
let [counts,setCounts] = useState([]); | ||
|
||
|
||
let rows = syncs.map((sync) => ({ | ||
timestamp: sync.startTime, | ||
count: sync.numRows, | ||
})) | ||
|
||
useEffect(()=>{ | ||
let counts = aggregateCountsByInterval(rows,aggregateType, undefined, new Date()); | ||
counts = counts.slice(0,29) | ||
counts = counts.reverse(); | ||
setCounts(counts) | ||
|
||
},[aggregateType, rows]) | ||
|
||
return <div> | ||
<div className='float-right'> | ||
<button className={aggregateType === "15min" ? "bg-gray-200 px-1 mx-1 rounded-md":"px-1 mx-1"} onClick={()=>setAggregateType('15min')}>15 mins</button> | ||
<button className={aggregateType === "hour" ? "bg-gray-200 px-1 mx-1 rounded-md":"px-1 mx-1"} onClick={()=>setAggregateType('hour')}>Hour</button> | ||
<button className={aggregateType === "day" ? "bg-gray-200 px-1 mx-1 rounded-md":"px-1 mx-1"} onClick={()=>setAggregateType('day')}>Day</button> | ||
<button className={aggregateType === "month" ? "bg-gray-200 px-1 mx-1 rounded-md":"px-1 mx-1"} onClick={()=>setAggregateType('month')}>Month</button> | ||
</div> | ||
<div><Label variant="body">Sync history</Label></div> | ||
|
||
<div className='flex space-x-2 justify-left ml-2'> | ||
{counts.map((count,i)=><GraphBar key={i} label={formatGraphLabel(new Date(count[0]),aggregateType)} count={count[1]}/>)} | ||
</div> | ||
</div> | ||
} | ||
|
||
type GraphBarProps = { | ||
count: number | undefined; | ||
label: string | ||
}; | ||
|
||
|
||
function formatGraphLabel(date:Date, aggregateType:String) { | ||
switch (aggregateType) { | ||
case "15min": | ||
return format(date, 'MMM dd HH:mm'); | ||
case "hour": | ||
return format(date, 'MMM dd HH:mm'); | ||
case "day": | ||
return format(date, 'MMM dd'); | ||
case "month": | ||
return format(date, 'MMM yy'); | ||
} | ||
} | ||
|
||
function GraphBar({label,count}:GraphBarProps){ | ||
let color = count && count >0 ? 'bg-green-500' : 'bg-gray-500'; | ||
let classNames = `relative w-10 h-24 rounded ${color}`; | ||
return <div className={"group"}> | ||
<div className={classNames}> | ||
<div className="group-hover:opacity-100 transition-opacity bg-gray-800 px-1 text-sm text-gray-100 rounded-md absolute left-1/2 | ||
-translate-x-1/2 translate-y-full opacity-0 m-4 mx-auto w-28 z-10 text-center"> | ||
<div>{label}</div> | ||
<div>{count}</div> | ||
</div> | ||
</div> | ||
</div> | ||
} | ||
|
||
|
||
export default CdcGraph; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
|
||
//React component to show a timeline of sync events. Each bar on the time line will | ||
//represent the number of |