Improve a bit workers. bug : Bundle reset after all backtest finish
This commit is contained in:
@@ -5,9 +5,11 @@ type IPieChart = {
|
||||
data: number[]
|
||||
labels: string[]
|
||||
colors: string[]
|
||||
width?: number
|
||||
height?: number
|
||||
}
|
||||
|
||||
const PieChart: React.FC<IPieChart> = ({ data, labels, colors }) => {
|
||||
const PieChart: React.FC<IPieChart> = ({ data, labels, colors, width = 150, height = 150 }) => {
|
||||
return (
|
||||
<>
|
||||
<Plot
|
||||
@@ -22,7 +24,7 @@ const PieChart: React.FC<IPieChart> = ({ data, labels, colors }) => {
|
||||
},
|
||||
]}
|
||||
layout={{
|
||||
height: 150,
|
||||
height: height,
|
||||
margin: {
|
||||
b: 20,
|
||||
l: 0,
|
||||
@@ -33,7 +35,7 @@ const PieChart: React.FC<IPieChart> = ({ data, labels, colors }) => {
|
||||
paper_bgcolor: 'rgba(0,0,0,0)',
|
||||
plot_bgcolor: 'rgba(0,0,0,0)',
|
||||
showlegend: false,
|
||||
width: 150,
|
||||
width: width,
|
||||
}}
|
||||
config={{
|
||||
displayModeBar: false,
|
||||
|
||||
@@ -17,7 +17,7 @@ const BundleBacktestRequestsSettings: React.FC = () => {
|
||||
const [sortBy, setSortBy] = useState<BundleBacktestRequestSortableColumn>(BundleBacktestRequestSortableColumn.CreatedAt)
|
||||
const [sortOrder, setSortOrder] = useState<string>('desc')
|
||||
const [nameContains, setNameContains] = useState<string>('')
|
||||
const [statusFilter, setStatusFilter] = useState<BundleBacktestRequestStatus | null>(BundleBacktestRequestStatus.Failed)
|
||||
const [statusFilter, setStatusFilter] = useState<BundleBacktestRequestStatus | null>(null)
|
||||
const [userIdFilter, setUserIdFilter] = useState<string>('')
|
||||
const [userNameContains, setUserNameContains] = useState<string>('')
|
||||
const [totalBacktestsMin, setTotalBacktestsMin] = useState<string>('')
|
||||
@@ -258,7 +258,7 @@ const BundleBacktestRequestsSettings: React.FC = () => {
|
||||
<span className="loading loading-spinner loading-sm ml-2"></span>
|
||||
)}
|
||||
</h3>
|
||||
<div className="grid grid-cols-3 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4">
|
||||
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4">
|
||||
{isLoadingSummary ? (
|
||||
// Show skeleton with all statuses set to 0
|
||||
<>
|
||||
|
||||
@@ -3,7 +3,7 @@ import {
|
||||
type BundleBacktestRequestListItemResponse,
|
||||
BundleBacktestRequestSortableColumn
|
||||
} from '../../../generated/ManagingApi'
|
||||
import {Table} from '../../../components/mollecules'
|
||||
import {Table, Toast} from '../../../components/mollecules'
|
||||
|
||||
interface IBundleBacktestRequestsTable {
|
||||
bundleRequests: BundleBacktestRequestListItemResponse[]
|
||||
@@ -68,6 +68,16 @@ const BundleBacktestRequestsTable: React.FC<IBundleBacktestRequestsTable> = ({
|
||||
return `${progress.toFixed(1)}%`
|
||||
}
|
||||
|
||||
const copyToClipboard = async (text: string) => {
|
||||
const toast = new Toast('Copying to clipboard...')
|
||||
try {
|
||||
await navigator.clipboard.writeText(text)
|
||||
toast.update('success', 'Request ID copied to clipboard!')
|
||||
} catch (err) {
|
||||
toast.update('error', 'Failed to copy to clipboard')
|
||||
}
|
||||
}
|
||||
|
||||
const SortableHeader = ({ column, label }: { column: BundleBacktestRequestSortableColumn; label: string }) => {
|
||||
const isActive = sortBy === column
|
||||
return (
|
||||
@@ -180,7 +190,23 @@ const BundleBacktestRequestsTable: React.FC<IBundleBacktestRequestsTable> = ({
|
||||
id: 'requestId',
|
||||
Header: () => <SortableHeader column={BundleBacktestRequestSortableColumn.RequestId} label="Request ID" />,
|
||||
accessor: (row: BundleBacktestRequestListItemResponse) => (
|
||||
<span className="font-mono text-xs">{row.requestId?.substring(0, 8)}...</span>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="font-mono text-xs">{row.requestId?.substring(0, 8)}...</span>
|
||||
{row.requestId && (
|
||||
<button
|
||||
className="btn btn-ghost btn-xs p-1 h-auto min-h-0"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
copyToClipboard(row.requestId || '')
|
||||
}}
|
||||
title="Copy Request ID"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" className="w-4 h-4">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M15.666 3.6A2.25 2.25 0 0013.5 2.25h-3c-1.03 0-1.9.693-2.166 1.6m5.332 0A2.25 2.25 0 0115.75 4.5v3.75m0 0v3.75m0-3.75h3.75m-3.75 0h-3.75M15 15.75a2.25 2.25 0 01-2.25 2.25H5.25A2.25 2.25 0 013 15.75V8.25a2.25 2.25 0 012.25-2.25h7.5A2.25 2.25 0 0115 8.25v7.5z" />
|
||||
</svg>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
},
|
||||
...(onDelete ? [{
|
||||
|
||||
@@ -3,7 +3,7 @@ import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import useApiUrlStore from '../../../app/store/apiStore'
|
||||
import {JobClient} from '../../../generated/ManagingApi'
|
||||
import {BottomMenuBar, Toast} from '../../../components/mollecules'
|
||||
import {BottomMenuBar, PieChart, Toast} from '../../../components/mollecules'
|
||||
|
||||
import JobsTable from './jobsTable'
|
||||
|
||||
@@ -13,7 +13,7 @@ const JobsSettings: React.FC = () => {
|
||||
const [pageSize, setPageSize] = useState(50)
|
||||
const [sortBy, setSortBy] = useState<string>('CreatedAt')
|
||||
const [sortOrder, setSortOrder] = useState<string>('desc')
|
||||
const [statusFilter, setStatusFilter] = useState<string>('Failed')
|
||||
const [statusFilter, setStatusFilter] = useState<string>('')
|
||||
const [jobTypeFilter, setJobTypeFilter] = useState<string>('')
|
||||
const [userIdFilter, setUserIdFilter] = useState<string>('')
|
||||
const [workerIdFilter, setWorkerIdFilter] = useState<string>('')
|
||||
@@ -146,7 +146,7 @@ const JobsSettings: React.FC = () => {
|
||||
}
|
||||
|
||||
const clearFilters = () => {
|
||||
setStatusFilter('Failed') // Reset to Failed instead of All
|
||||
setStatusFilter('') // Reset to All
|
||||
setJobTypeFilter('')
|
||||
setUserIdFilter('')
|
||||
setWorkerIdFilter('')
|
||||
@@ -195,7 +195,35 @@ const JobsSettings: React.FC = () => {
|
||||
</svg>
|
||||
Status Overview
|
||||
</h3>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 items-start">
|
||||
{/* Pie Chart */}
|
||||
<div className="flex justify-center">
|
||||
<PieChart
|
||||
data={jobSummary.statusSummary.map(item => item.count || 0)}
|
||||
labels={jobSummary.statusSummary.map(item => item.status || 'Unknown')}
|
||||
colors={jobSummary.statusSummary.map(item => {
|
||||
const statusLower = (item.status || '').toLowerCase()
|
||||
switch (statusLower) {
|
||||
case 'pending':
|
||||
return '#fbbf24' // warning color
|
||||
case 'running':
|
||||
return '#3b82f6' // info color
|
||||
case 'completed':
|
||||
return '#10b981' // success color
|
||||
case 'failed':
|
||||
return '#ef4444' // error color
|
||||
case 'cancelled':
|
||||
return '#6b7280' // neutral color
|
||||
default:
|
||||
return '#9ca3af' // default gray
|
||||
}
|
||||
})}
|
||||
width={300}
|
||||
height={300}
|
||||
/>
|
||||
</div>
|
||||
{/* Status Tiles */}
|
||||
<div className="grid grid-cols-2 md:grid-cols-2 lg:grid-cols-2 gap-4">
|
||||
{jobSummary.statusSummary.map((statusItem) => {
|
||||
const statusLower = (statusItem.status || '').toLowerCase()
|
||||
let statusIcon, statusDesc, statusColor
|
||||
@@ -271,6 +299,7 @@ const JobsSettings: React.FC = () => {
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -576,7 +605,6 @@ const JobsSettings: React.FC = () => {
|
||||
</a>
|
||||
</li>
|
||||
</BottomMenuBar>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user