Stop calling submissions trades in dashboard
All checks were successful
deploy / deploy (push) Successful in 32s
All checks were successful
deploy / deploy (push) Successful in 32s
Proof: Dashboard copy now describes durable submitted quote responses as submissions rather than successful trades or asset deltas, and regression coverage locks the new wording in place. Assumptions: The current durable execution result still means quote-response submission, not settled execution or realized inventory change. Still fake: The backend still stores and aggregates these rows under trade-oriented names, and the full quote lifecycle model is still the active follow-up turn.
This commit is contained in:
parent
7ea1576ba7
commit
7ddefb500e
4 changed files with 56 additions and 15 deletions
|
|
@ -1,4 +1,5 @@
|
||||||
import { formatAge, formatBoolean, formatEur, formatTimestamp, signedClass, truncateMiddle } from '../lib/format.js';
|
import { formatAge, formatBoolean, formatEur, formatTimestamp, signedClass, truncateMiddle } from '../lib/format.js';
|
||||||
|
import { SUBMISSION_COPY } from '../lib/submissionCopy.js';
|
||||||
|
|
||||||
function statusSubtitle(label, status, websocketState) {
|
function statusSubtitle(label, status, websocketState) {
|
||||||
switch (label) {
|
switch (label) {
|
||||||
|
|
@ -8,8 +9,8 @@ function statusSubtitle(label, status, websocketState) {
|
||||||
return formatTimestamp(status.market_observed_at);
|
return formatTimestamp(status.market_observed_at);
|
||||||
case 'Inventory Freshness':
|
case 'Inventory Freshness':
|
||||||
return formatTimestamp(status.inventory_observed_at);
|
return formatTimestamp(status.inventory_observed_at);
|
||||||
case 'Trading':
|
case SUBMISSION_COPY.statusTileLabel:
|
||||||
return 'Successful submissions from durable history';
|
return SUBMISSION_COPY.statusTileSubtitle;
|
||||||
default:
|
default:
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
@ -25,8 +26,8 @@ export default function StatusBar({ status, websocketState }) {
|
||||||
['Alerts', `${status.active_alert_count || 0} ${status.highest_alert_severity ? `(${status.highest_alert_severity})` : ''}`.trim()],
|
['Alerts', `${status.active_alert_count || 0} ${status.highest_alert_severity ? `(${status.highest_alert_severity})` : ''}`.trim()],
|
||||||
['Strategy Armed', formatBoolean(status.strategy_armed)],
|
['Strategy Armed', formatBoolean(status.strategy_armed)],
|
||||||
['Executor Armed', formatBoolean(status.executor_armed)],
|
['Executor Armed', formatBoolean(status.executor_armed)],
|
||||||
['Trading', `${status.recent_trade_count || 0} trades`],
|
[SUBMISSION_COPY.statusTileLabel, `${status.recent_trade_count || 0} ${SUBMISSION_COPY.statusTileValueSuffix}`],
|
||||||
['Last Trade', formatTimestamp(status.last_successful_trade_at)],
|
[SUBMISSION_COPY.lastStatusTileLabel, formatTimestamp(status.last_successful_trade_at)],
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
15
src/operator-dashboard/static/lib/submissionCopy.js
Normal file
15
src/operator-dashboard/static/lib/submissionCopy.js
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
export const SUBMISSION_COPY = {
|
||||||
|
statusTileLabel: 'Submissions',
|
||||||
|
statusTileSubtitle: 'Successful quote-response submissions from durable history',
|
||||||
|
statusTileValueSuffix: 'submissions',
|
||||||
|
lastStatusTileLabel: 'Last Submission',
|
||||||
|
recentMetricLabel: 'Recent submissions',
|
||||||
|
recentMetricValueSuffix: 'submissions',
|
||||||
|
termsEyebrow: 'Submission activity',
|
||||||
|
termsTitle: 'Recent submitted quote terms',
|
||||||
|
termsEmpty: 'No submitted quote responses are available yet.',
|
||||||
|
ledgerTitle: 'Submitted quote responses',
|
||||||
|
ledgerSubtitle: 'PostgreSQL-backed pagination of executor submissions',
|
||||||
|
ledgerEmpty: 'No submitted quote responses are stored yet.',
|
||||||
|
ledgerCountLabel: (page, totalPages, total) => `Page ${page} of ${totalPages} - ${total} submitted quote responses`,
|
||||||
|
};
|
||||||
|
|
@ -5,6 +5,7 @@ import MetricCard from '../components/MetricCard.jsx';
|
||||||
import Pill from '../components/Pill.jsx';
|
import Pill from '../components/Pill.jsx';
|
||||||
import TableFrame from '../components/TableFrame.jsx';
|
import TableFrame from '../components/TableFrame.jsx';
|
||||||
import { formatEur, formatTimestamp, stringifyJson, truncateMiddle } from '../lib/format.js';
|
import { formatEur, formatTimestamp, stringifyJson, truncateMiddle } from '../lib/format.js';
|
||||||
|
import { SUBMISSION_COPY } from '../lib/submissionCopy.js';
|
||||||
|
|
||||||
function buildInitialEstimateForm(balances, withdrawalDefaults) {
|
function buildInitialEstimateForm(balances, withdrawalDefaults) {
|
||||||
const firstAssetId = balances?.[0]?.asset_id || '';
|
const firstAssetId = balances?.[0]?.asset_id || '';
|
||||||
|
|
@ -204,7 +205,7 @@ function QuotesTable({ items }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function AssetChangeTable({ items }) {
|
function AssetChangeTable({ items }) {
|
||||||
if (!items?.length) return <EmptyState>No successful trades are available yet.</EmptyState>;
|
if (!items?.length) return <EmptyState>{SUBMISSION_COPY.termsEmpty}</EmptyState>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableFrame>
|
<TableFrame>
|
||||||
|
|
@ -213,8 +214,8 @@ function AssetChangeTable({ items }) {
|
||||||
<tr>
|
<tr>
|
||||||
<th>Observed</th>
|
<th>Observed</th>
|
||||||
<th>Quote</th>
|
<th>Quote</th>
|
||||||
<th>Spend</th>
|
<th>Input</th>
|
||||||
<th>Receive</th>
|
<th>Output</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|
@ -233,7 +234,7 @@ function AssetChangeTable({ items }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function TradesTable({ items }) {
|
function TradesTable({ items }) {
|
||||||
if (!items?.length) return <EmptyState>No successful trades are stored yet.</EmptyState>;
|
if (!items?.length) return <EmptyState>{SUBMISSION_COPY.ledgerEmpty}</EmptyState>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableFrame>
|
<TableFrame>
|
||||||
|
|
@ -446,9 +447,9 @@ export default function FundsPage({
|
||||||
value={formatEur(profitability.trading_contribution_eure)}
|
value={formatEur(profitability.trading_contribution_eure)}
|
||||||
/>
|
/>
|
||||||
<MetricCard
|
<MetricCard
|
||||||
label="Recent trading"
|
label={SUBMISSION_COPY.recentMetricLabel}
|
||||||
meta={formatTimestamp(profitability.last_successful_trade_at)}
|
meta={formatTimestamp(profitability.last_successful_trade_at)}
|
||||||
value={`${profitability.recent_trade_count || 0} trades`}
|
value={`${profitability.recent_trade_count || 0} ${SUBMISSION_COPY.recentMetricValueSuffix}`}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="panel-subtitle">
|
<div className="panel-subtitle">
|
||||||
|
|
@ -568,8 +569,8 @@ export default function FundsPage({
|
||||||
<div className="panel">
|
<div className="panel">
|
||||||
<div className="panel-head">
|
<div className="panel-head">
|
||||||
<div>
|
<div>
|
||||||
<div className="eyebrow">Trade-driven changes</div>
|
<div className="eyebrow">{SUBMISSION_COPY.termsEyebrow}</div>
|
||||||
<h3>Recent asset deltas</h3>
|
<h3>{SUBMISSION_COPY.termsTitle}</h3>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<AssetChangeTable items={funds.trade_asset_changes} />
|
<AssetChangeTable items={funds.trade_asset_changes} />
|
||||||
|
|
@ -580,13 +581,13 @@ export default function FundsPage({
|
||||||
<div className="panel-head">
|
<div className="panel-head">
|
||||||
<div>
|
<div>
|
||||||
<div className="eyebrow">Durable ledger</div>
|
<div className="eyebrow">Durable ledger</div>
|
||||||
<h3>Successful trades</h3>
|
<h3>{SUBMISSION_COPY.ledgerTitle}</h3>
|
||||||
</div>
|
</div>
|
||||||
<div className="status-subtle">PostgreSQL-backed pagination</div>
|
<div className="status-subtle">{SUBMISSION_COPY.ledgerSubtitle}</div>
|
||||||
</div>
|
</div>
|
||||||
<TradesTable items={trades.items} />
|
<TradesTable items={trades.items} />
|
||||||
<div className="pagination">
|
<div className="pagination">
|
||||||
<div className="status-subtle">{`Page ${trades.page} of ${trades.total_pages} - ${trades.total} successful trades`}</div>
|
<div className="status-subtle">{SUBMISSION_COPY.ledgerCountLabel(trades.page, trades.total_pages, trades.total)}</div>
|
||||||
<div className="button-row">
|
<div className="button-row">
|
||||||
<button
|
<button
|
||||||
className="button secondary"
|
className="button secondary"
|
||||||
|
|
|
||||||
24
test/submission-copy.test.mjs
Normal file
24
test/submission-copy.test.mjs
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
import test from 'node:test';
|
||||||
|
import assert from 'node:assert/strict';
|
||||||
|
|
||||||
|
import { SUBMISSION_COPY } from '../src/operator-dashboard/static/lib/submissionCopy.js';
|
||||||
|
|
||||||
|
test('submission copy does not present submissions as trades', () => {
|
||||||
|
const text = [
|
||||||
|
SUBMISSION_COPY.statusTileLabel,
|
||||||
|
SUBMISSION_COPY.statusTileSubtitle,
|
||||||
|
SUBMISSION_COPY.recentMetricLabel,
|
||||||
|
SUBMISSION_COPY.termsEyebrow,
|
||||||
|
SUBMISSION_COPY.termsTitle,
|
||||||
|
SUBMISSION_COPY.termsEmpty,
|
||||||
|
SUBMISSION_COPY.ledgerTitle,
|
||||||
|
SUBMISSION_COPY.ledgerSubtitle,
|
||||||
|
SUBMISSION_COPY.ledgerEmpty,
|
||||||
|
SUBMISSION_COPY.ledgerCountLabel(1, 2, 3),
|
||||||
|
].join(' ').toLowerCase();
|
||||||
|
|
||||||
|
assert.ok(text.includes('submission'));
|
||||||
|
assert.ok(!text.includes('successful trades'));
|
||||||
|
assert.ok(!text.includes('asset deltas'));
|
||||||
|
assert.ok(!text.includes('trade-driven'));
|
||||||
|
});
|
||||||
Loading…
Add table
Reference in a new issue