import { useData, usePublish, type PanelRef } from '@jaspers-ai/sdk' import { useEffect, useState } from 'react' import { fmt } from './format' import './styles.css' interface Order { id: string symbol: string | null side: string | null type: string | null time_in_force: string | null qty: number | null notional: number | null filled_qty: number | null limit_price: number | null stop_price: number | null filled_avg_price: number | null status: string | null submitted_at: string | null parent_id: string | null } interface State { status?: 'open' | 'closed' | 'all' limit?: number live_account?: boolean } const OPEN = new Set(['new', 'accepted', 'pending_new', 'partially_filled', 'accepted_for_bidding', 'held', 'calculated', 'pending_replace']) function statusClass(status: string | null): string { if (status === 'filled') return 'al-status-filled' if (status && OPEN.has(status)) return 'al-status-open' if (status === 'rejected' || status === 'suspended') return 'al-status-bad' return 'al-status-dead' } export function Blotter({ panel }: { panel: PanelRef }) { const state = useData(`workspaces/${panel.workspaceId}/panels/${panel.id}/state`) as State | undefined if (state === undefined) return
Loading…
return ({error}
) : !data ? (Loading…
) : rows.length === 0 ? (No {status === 'all' ? '' : `${status} `}orders.
) : (| Submitted | Symbol | Side | Type | Qty | Filled | Limit | Stop | Avg fill | TIF | Status | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| {o.submitted_at?.replace('T', ' ').slice(0, 19) ?? '–'} | {o.parent_id ? `↳ ${o.symbol}` : o.symbol} | {o.side} | {o.type} | {o.qty !== null ? fmt(o.qty, 0) : o.notional !== null ? `$${fmt(o.notional)}` : '–'} | {fmt(o.filled_qty, 0)} | {fmt(o.limit_price)} | {fmt(o.stop_price)} | {fmt(o.filled_avg_price)} | {o.time_in_force} | {o.status} |
{!cancellable && !p ? null : p === undefined ? (
) : p === 'confirm' ? (
<>
{' '}
>
) : p === 'cancelling' ? (
|