feat: show document title and link in competitive signals panel
ci/woodpecker/push/test Pipeline was successful
ci/woodpecker/push/build-2 Pipeline was successful
ci/woodpecker/push/build-3 Pipeline was successful
ci/woodpecker/push/build-1 Pipeline was successful
ci/woodpecker/push/finalize Pipeline was successful
Build and Push / lint-and-test (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.adapters.broker_adapter name:broker-adapter]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.aggregation.worker name:aggregation]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.extractor.worker name:extractor]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.ingestion.worker name:ingestion]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.lake_publisher.worker name:lake-publisher]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.parser.worker name:parser]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.recommendation.worker name:recommendation]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.scheduler.app name:scheduler]) (push) Has been cancelled
Build and Push / build-services (map[cmd:uvicorn services.api.app:app --host 0.0.0.0 --port 8000 name:query-api]) (push) Has been cancelled
Build and Push / build-services (map[cmd:uvicorn services.risk.app:app --host 0.0.0.0 --port 8000 name:risk]) (push) Has been cancelled
Build and Push / build-services (map[cmd:uvicorn services.symbol_registry.app:app --host 0.0.0.0 --port 8000 name:symbol-registry]) (push) Has been cancelled
Build and Push / build-services (map[cmd:uvicorn services.trading.app:app --host 0.0.0.0 --port 8000 name:trading-engine]) (push) Has been cancelled
Build and Push / build-dashboard (push) Has been cancelled
Build and Push / build-superset (push) Has been cancelled
Build and Push / integration-test (push) Has been cancelled
Build and Push / beta-gate (push) Has been cancelled
ci/woodpecker/push/test Pipeline was successful
ci/woodpecker/push/build-2 Pipeline was successful
ci/woodpecker/push/build-3 Pipeline was successful
ci/woodpecker/push/build-1 Pipeline was successful
ci/woodpecker/push/finalize Pipeline was successful
Build and Push / lint-and-test (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.adapters.broker_adapter name:broker-adapter]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.aggregation.worker name:aggregation]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.extractor.worker name:extractor]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.ingestion.worker name:ingestion]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.lake_publisher.worker name:lake-publisher]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.parser.worker name:parser]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.recommendation.worker name:recommendation]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.scheduler.app name:scheduler]) (push) Has been cancelled
Build and Push / build-services (map[cmd:uvicorn services.api.app:app --host 0.0.0.0 --port 8000 name:query-api]) (push) Has been cancelled
Build and Push / build-services (map[cmd:uvicorn services.risk.app:app --host 0.0.0.0 --port 8000 name:risk]) (push) Has been cancelled
Build and Push / build-services (map[cmd:uvicorn services.symbol_registry.app:app --host 0.0.0.0 --port 8000 name:symbol-registry]) (push) Has been cancelled
Build and Push / build-services (map[cmd:uvicorn services.trading.app:app --host 0.0.0.0 --port 8000 name:trading-engine]) (push) Has been cancelled
Build and Push / build-dashboard (push) Has been cancelled
Build and Push / build-superset (push) Has been cancelled
Build and Push / integration-test (push) Has been cancelled
Build and Push / beta-gate (push) Has been cancelled
Replace raw UUID with a linked document title in both the collapsed row (using the empty space on the right) and the expanded detail view. Uses useDocument hook to fetch the title, falls back to truncated UUID while loading. Clicking the link navigates to the document detail page.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { useParams, useNavigate } from '@tanstack/react-router';
|
import { useParams, useNavigate, Link } from '@tanstack/react-router';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import {
|
import {
|
||||||
useCompany,
|
useCompany,
|
||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
useTrends,
|
useTrends,
|
||||||
useTrendHistory,
|
useTrendHistory,
|
||||||
useMarketPrices,
|
useMarketPrices,
|
||||||
|
useDocument,
|
||||||
} from '../api/hooks';
|
} from '../api/hooks';
|
||||||
import { StatusBadge, ConfidenceBar, LoadingSpinner, Card } from '../components/ui';
|
import { StatusBadge, ConfidenceBar, LoadingSpinner, Card } from '../components/ui';
|
||||||
import { DataTable, type Column } from '../components/DataTable';
|
import { DataTable, type Column } from '../components/DataTable';
|
||||||
@@ -444,62 +445,7 @@ function CompetitiveSignalsPanel({ signals }: { signals: CompetitiveSignal[] })
|
|||||||
) : (
|
) : (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
{signals.map((s) => (
|
{signals.map((s) => (
|
||||||
<div key={s.id}>
|
<SignalRow key={s.id} signal={s} expanded={expandedId === s.id} onToggle={() => setExpandedId(expandedId === s.id ? null : s.id)} />
|
||||||
<div
|
|
||||||
className="flex items-center justify-between rounded-lg border border-cyan-700/30 bg-cyan-900/10 p-3 cursor-pointer hover:border-cyan-500/50"
|
|
||||||
onClick={() => setExpandedId(expandedId === s.id ? null : s.id)}
|
|
||||||
>
|
|
||||||
<div className="flex items-center gap-3">
|
|
||||||
<span className="rounded bg-cyan-900/40 border border-cyan-700/50 px-1.5 py-0.5 text-[10px] font-medium text-cyan-400">COMPETITIVE</span>
|
|
||||||
<span className="font-mono text-sm text-brand-300">{s.source_ticker}</span>
|
|
||||||
<span className="text-xs text-gray-400">→</span>
|
|
||||||
<StatusBadge status={s.catalyst_type} />
|
|
||||||
<StatusBadge status={s.signal_direction} />
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-3">
|
|
||||||
<ConfidenceBar value={s.signal_strength} />
|
|
||||||
<span className="text-xs text-gray-500">{new Date(s.computed_at).toLocaleDateString()}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{expandedId === s.id && (
|
|
||||||
<Card className="mt-1 ml-4">
|
|
||||||
<dl className="grid grid-cols-2 gap-x-6 gap-y-2 text-xs sm:grid-cols-3">
|
|
||||||
<div>
|
|
||||||
<dt className="text-gray-500">Source Ticker</dt>
|
|
||||||
<dd className="font-mono text-gray-200">{s.source_ticker}</dd>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<dt className="text-gray-500">Target Ticker</dt>
|
|
||||||
<dd className="font-mono text-gray-200">{s.target_ticker}</dd>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<dt className="text-gray-500">Catalyst Type</dt>
|
|
||||||
<dd className="text-gray-200">{s.catalyst_type}</dd>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<dt className="text-gray-500">Pattern Confidence</dt>
|
|
||||||
<dd><ConfidenceBar value={s.pattern_confidence} /></dd>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<dt className="text-gray-500">Signal Strength</dt>
|
|
||||||
<dd><ConfidenceBar value={s.signal_strength} /></dd>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<dt className="text-gray-500">Relationship Strength</dt>
|
|
||||||
<dd><ConfidenceBar value={s.relationship_strength} /></dd>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<dt className="text-gray-500">Source Document</dt>
|
|
||||||
<dd className="font-mono text-gray-400 text-[10px]">{s.source_document_id}</dd>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<dt className="text-gray-500">Computed At</dt>
|
|
||||||
<dd className="text-gray-200">{new Date(s.computed_at).toLocaleString()}</dd>
|
|
||||||
</div>
|
|
||||||
</dl>
|
|
||||||
</Card>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -507,6 +453,88 @@ function CompetitiveSignalsPanel({ signals }: { signals: CompetitiveSignal[] })
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function SignalRow({ signal: s, expanded, onToggle }: { signal: CompetitiveSignal; expanded: boolean; onToggle: () => void }) {
|
||||||
|
const { data: doc } = useDocument(s.source_document_id);
|
||||||
|
const docLabel = doc?.title ?? `doc:${s.source_document_id.slice(0, 8)}…`;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
className="flex items-center justify-between rounded-lg border border-cyan-700/30 bg-cyan-900/10 p-3 cursor-pointer hover:border-cyan-500/50"
|
||||||
|
onClick={onToggle}
|
||||||
|
>
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<span className="rounded bg-cyan-900/40 border border-cyan-700/50 px-1.5 py-0.5 text-[10px] font-medium text-cyan-400">COMPETITIVE</span>
|
||||||
|
<span className="font-mono text-sm text-brand-300">{s.source_ticker}</span>
|
||||||
|
<span className="text-xs text-gray-400">→</span>
|
||||||
|
<StatusBadge status={s.catalyst_type} />
|
||||||
|
<StatusBadge status={s.signal_direction} />
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<Link
|
||||||
|
to="/documents/$id"
|
||||||
|
params={{ id: s.source_document_id }}
|
||||||
|
className="max-w-[180px] truncate text-xs text-brand-400 hover:underline"
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
title={doc?.title ?? s.source_document_id}
|
||||||
|
>
|
||||||
|
{docLabel}
|
||||||
|
</Link>
|
||||||
|
<ConfidenceBar value={s.signal_strength} />
|
||||||
|
<span className="text-xs text-gray-500">{new Date(s.computed_at).toLocaleDateString()}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{expanded && (
|
||||||
|
<Card className="mt-1 ml-4">
|
||||||
|
<dl className="grid grid-cols-2 gap-x-6 gap-y-2 text-xs sm:grid-cols-3">
|
||||||
|
<div>
|
||||||
|
<dt className="text-gray-500">Source Ticker</dt>
|
||||||
|
<dd className="font-mono text-gray-200">{s.source_ticker}</dd>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<dt className="text-gray-500">Target Ticker</dt>
|
||||||
|
<dd className="font-mono text-gray-200">{s.target_ticker}</dd>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<dt className="text-gray-500">Catalyst Type</dt>
|
||||||
|
<dd className="text-gray-200">{s.catalyst_type}</dd>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<dt className="text-gray-500">Pattern Confidence</dt>
|
||||||
|
<dd><ConfidenceBar value={s.pattern_confidence} /></dd>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<dt className="text-gray-500">Signal Strength</dt>
|
||||||
|
<dd><ConfidenceBar value={s.signal_strength} /></dd>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<dt className="text-gray-500">Relationship Strength</dt>
|
||||||
|
<dd><ConfidenceBar value={s.relationship_strength} /></dd>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<dt className="text-gray-500">Source Document</dt>
|
||||||
|
<dd>
|
||||||
|
<Link
|
||||||
|
to="/documents/$id"
|
||||||
|
params={{ id: s.source_document_id }}
|
||||||
|
className="text-brand-400 hover:underline"
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
>
|
||||||
|
{docLabel}
|
||||||
|
</Link>
|
||||||
|
</dd>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<dt className="text-gray-500">Computed At</dt>
|
||||||
|
<dd className="text-gray-200">{new Date(s.computed_at).toLocaleString()}</dd>
|
||||||
|
</div>
|
||||||
|
</dl>
|
||||||
|
</Card>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function DecisionsPanel({ decisions }: { decisions: CorporateDecision[] }) {
|
function DecisionsPanel({ decisions }: { decisions: CorporateDecision[] }) {
|
||||||
return (
|
return (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
|
|||||||
Reference in New Issue
Block a user