Move tape filters into page actions

- Remove legacy per-pane load older controls
- Reposition tape filter controls into the route actions area
- Tidy top bar layout and live fetch URL building
This commit is contained in:
dirtydishes 2026-05-04 14:06:31 -04:00
parent c0219233d3
commit 8ff62cc4f9
2 changed files with 16 additions and 72 deletions

View file

@ -168,6 +168,7 @@ input {
z-index: 20;
display: flex;
align-items: center;
justify-content: flex-end;
gap: 12px;
padding: 10px 20px;
background: rgba(7, 10, 14, 0.92);
@ -210,18 +211,20 @@ input {
.terminal-topbar-actions {
display: flex;
align-items: center;
justify-content: space-between;
justify-content: flex-end;
gap: 12px;
min-width: 0;
width: 100%;
width: auto;
margin-left: auto;
}
.terminal-topbar-controls {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 10px;
min-width: 0;
flex: 1 1 auto;
flex: 0 1 auto;
}
.terminal-topbar-mode {
@ -237,7 +240,7 @@ input {
flex-direction: column;
gap: 4px;
min-width: clamp(220px, 24vw, 360px);
flex: 1 1 clamp(220px, 24vw, 360px);
flex: 0 1 clamp(220px, 24vw, 360px);
}
.terminal-filter-label {
@ -810,30 +813,6 @@ h3 {
white-space: nowrap;
}
.load-older {
display: flex;
flex: 0 0 auto;
align-items: center;
justify-content: center;
gap: 10px;
padding: 4px 0 0;
font-size: 0.76rem;
color: var(--muted);
}
.load-older button {
min-width: 112px;
white-space: nowrap;
}
.load-older span {
max-width: 260px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: var(--danger);
}
.missed-count {
width: 86px;
font-size: 0.72rem;
@ -1585,15 +1564,18 @@ h3 {
.terminal-topbar {
position: static;
align-items: center;
justify-content: flex-end;
padding: 10px 16px;
}
.terminal-topbar-actions {
justify-content: space-between;
justify-content: flex-end;
margin-left: auto;
width: auto;
}
.terminal-topbar-controls {
flex: 1 1 auto;
flex: 0 1 auto;
}
.flow-filter-popover-panel {

View file

@ -2693,7 +2693,9 @@ const useLiveSession = (
appendOptionFlowFilters(params, subscription.filters);
}
appendLiveScopeParams(params, subscription);
const response = await fetch(buildApiUrl(`${endpoint}?${params.toString()}`));
const url = new URL(buildApiUrl(endpoint));
url.search = params.toString();
const response = await fetch(url.toString());
if (!response.ok) {
const detail = await readErrorDetail(response);
throw new Error(detail || `HTTP ${response.status}`);
@ -2844,39 +2846,6 @@ const TapeControls = ({ paused, onTogglePause, isAtTop, missed, onJump }: TapeCo
);
};
type LoadOlderControlProps = {
channel: LiveSubscription["channel"];
};
const LoadOlderControl = ({ channel }: LoadOlderControlProps) => {
const state = useTerminal();
const subscription = state.liveSession.manifest.find((candidate) => candidate.channel === channel);
if (state.mode !== "live" || !subscription || !(subscription.channel in LIVE_HISTORY_ENDPOINTS)) {
return null;
}
const key = getLiveSubscriptionKey(subscription);
const cursor = state.liveSession.historyCursors[key];
const loading = Boolean(state.liveSession.historyLoading[key]);
const error = state.liveSession.historyErrors[key];
if (!cursor && !loading && !error) {
return null;
}
return (
<div className="load-older">
<button
type="button"
onClick={() => void state.liveSession.loadOlder(channel)}
disabled={!cursor || loading}
>
{loading ? "Loading older" : cursor ? "Load older" : "No more history"}
</button>
{error ? <span>{error}</span> : null}
</div>
);
};
type CandleChartProps = {
ticker: string;
intervalMs: number;
@ -5615,7 +5584,6 @@ const OptionsPane = ({ limit }: OptionsPaneProps) => {
</div>
</div>
)}
{!limit ? <LoadOlderControl channel="options" /> : null}
</div>
</Pane>
);
@ -5710,7 +5678,6 @@ const EquitiesPane = ({ limit }: EquitiesPaneProps) => {
</div>
</div>
)}
{!limit ? <LoadOlderControl channel="equities" /> : null}
</div>
</Pane>
);
@ -5849,7 +5816,6 @@ const FlowPane = ({ limit, title = "Flow" }: FlowPaneProps) => {
</div>
</div>
)}
{!limit ? <LoadOlderControl channel="flow" /> : null}
</div>
</Pane>
);
@ -5948,7 +5914,6 @@ const AlertsPane = ({ limit, withStrip = false, className }: AlertsPaneProps) =>
</div>
</div>
)}
{!limit ? <LoadOlderControl channel="alerts" /> : null}
</div>
</Pane>
);
@ -6034,7 +5999,6 @@ const ClassifierPane = ({ limit, className }: ClassifierPaneProps) => {
</div>
</div>
)}
{!limit ? <LoadOlderControl channel="classifier-hits" /> : null}
</div>
</Pane>
);
@ -6128,7 +6092,6 @@ const DarkPane = ({ limit, className }: DarkPaneProps) => {
</div>
</div>
)}
{!limit ? <LoadOlderControl channel="inferred-dark" /> : null}
</div>
</Pane>
);
@ -6323,7 +6286,6 @@ export function TerminalAppShell({ children }: { children: ReactNode }) {
</button>
</span>
) : null}
<FlowFilterControls />
<label className="terminal-filter">
<span className="terminal-filter-label">Ticker</span>
<span className="terminal-filter-field">
@ -6405,7 +6367,7 @@ export function OverviewRoute() {
export function TapeRoute() {
return (
<PageFrame title="Tape">
<PageFrame title="Tape" actions={<FlowFilterControls />}>
<div className="page-grid page-grid-tape">
<OptionsPane />
<EquitiesPane />