forked from boos/BoosAPI
make proxy trace panel collapsible (#327)
This commit is contained in:
@@ -390,6 +390,74 @@ describe('ProxyLogs server-driven page', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('allows collapsing and expanding the debug trace panel to reduce page footprint', async () => {
|
||||
let root!: WebTestRenderer;
|
||||
|
||||
try {
|
||||
await act(async () => {
|
||||
root = create(
|
||||
<MemoryRouter initialEntries={['/logs']}>
|
||||
<ToastProvider>
|
||||
<ProxyLogs />
|
||||
</ToastProvider>
|
||||
</MemoryRouter>,
|
||||
);
|
||||
});
|
||||
await flushMicrotasks();
|
||||
|
||||
const toggleButton = root.root.find((node) => (
|
||||
node.type === 'button'
|
||||
&& typeof node.props.onClick === 'function'
|
||||
&& node.props['data-debug-trace-panel-toggle'] === true
|
||||
));
|
||||
const panelBody = root.root.find((node) => (
|
||||
node.type === 'div'
|
||||
&& node.props['data-debug-trace-panel-body'] === true
|
||||
));
|
||||
|
||||
expect(toggleButton.props['aria-expanded']).toBe(true);
|
||||
expect(String(panelBody.props.className || '')).toContain('is-open');
|
||||
|
||||
await act(async () => {
|
||||
toggleButton.props.onClick();
|
||||
});
|
||||
await flushMicrotasks();
|
||||
|
||||
const collapsedToggleButton = root.root.find((node) => (
|
||||
node.type === 'button'
|
||||
&& typeof node.props.onClick === 'function'
|
||||
&& node.props['data-debug-trace-panel-toggle'] === true
|
||||
));
|
||||
const collapsedPanelBody = root.root.find((node) => (
|
||||
node.type === 'div'
|
||||
&& node.props['data-debug-trace-panel-body'] === true
|
||||
));
|
||||
|
||||
expect(collapsedToggleButton.props['aria-expanded']).toBe(false);
|
||||
expect(String(collapsedPanelBody.props.className || '')).not.toContain('is-open');
|
||||
|
||||
await act(async () => {
|
||||
collapsedToggleButton.props.onClick();
|
||||
});
|
||||
await flushMicrotasks();
|
||||
|
||||
const expandedToggleButton = root.root.find((node) => (
|
||||
node.type === 'button'
|
||||
&& typeof node.props.onClick === 'function'
|
||||
&& node.props['data-debug-trace-panel-toggle'] === true
|
||||
));
|
||||
const expandedPanelBody = root.root.find((node) => (
|
||||
node.type === 'div'
|
||||
&& node.props['data-debug-trace-panel-body'] === true
|
||||
));
|
||||
|
||||
expect(expandedToggleButton.props['aria-expanded']).toBe(true);
|
||||
expect(String(expandedPanelBody.props.className || '')).toContain('is-open');
|
||||
} finally {
|
||||
root?.unmount();
|
||||
}
|
||||
});
|
||||
|
||||
it('opens debug trace detail on demand instead of preloading the first trace inline', async () => {
|
||||
let root!: WebTestRenderer;
|
||||
|
||||
|
||||
@@ -622,6 +622,7 @@ export default function ProxyLogs() {
|
||||
const [showDebugSettingsModal, setShowDebugSettingsModal] = useState(false);
|
||||
const [debugPanelLoading, setDebugPanelLoading] = useState(false);
|
||||
const [debugPanelSaving, setDebugPanelSaving] = useState(false);
|
||||
const [debugTracePanelExpanded, setDebugTracePanelExpanded] = useState(true);
|
||||
const [debugSettings, setDebugSettings] = useState<ProxyDebugSettingsState>(DEFAULT_PROXY_DEBUG_SETTINGS);
|
||||
const [debugDraftSettings, setDebugDraftSettings] = useState<ProxyDebugSettingsState>(DEFAULT_PROXY_DEBUG_SETTINGS);
|
||||
const [debugTraces, setDebugTraces] = useState<ProxyDebugTraceListItem[]>([]);
|
||||
@@ -994,6 +995,9 @@ export default function ProxyLogs() {
|
||||
const updated = await api.updateRuntimeSettings(buildProxyDebugSettingsPayload(nextSettings));
|
||||
const normalized = normalizeProxyDebugSettings(updated);
|
||||
applyLoadedDebugSettings(normalized, { syncDraft: true });
|
||||
if (normalized.proxyDebugTraceEnabled) {
|
||||
setDebugTracePanelExpanded(true);
|
||||
}
|
||||
if (options?.closeAfterSave) {
|
||||
setShowDebugSettingsModal(false);
|
||||
}
|
||||
@@ -1542,6 +1546,29 @@ export default function ProxyLogs() {
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-ghost"
|
||||
style={{ border: '1px solid var(--color-border)' }}
|
||||
aria-expanded={debugTracePanelExpanded}
|
||||
data-debug-trace-panel-toggle
|
||||
onClick={() => setDebugTracePanelExpanded((current) => !current)}
|
||||
>
|
||||
<svg
|
||||
width="14"
|
||||
height="14"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
style={{
|
||||
transform: debugTracePanelExpanded ? 'rotate(180deg)' : 'rotate(0deg)',
|
||||
transition: 'transform 0.2s ease',
|
||||
}}
|
||||
>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
|
||||
</svg>
|
||||
{debugTracePanelExpanded ? '收起追踪面板' : '展开追踪面板'}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className={debugSettings.proxyDebugTraceEnabled ? 'btn btn-ghost btn-ghost-active' : 'btn btn-ghost'}
|
||||
@@ -1586,7 +1613,13 @@ export default function ProxyLogs() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="card" style={{ marginBottom: 12, padding: 12, overflowX: 'auto' }}>
|
||||
<div
|
||||
className={`anim-collapse ${debugTracePanelExpanded ? 'is-open' : ''}`.trim()}
|
||||
data-debug-trace-panel-body
|
||||
style={{ marginBottom: debugTracePanelExpanded ? 12 : 0 }}
|
||||
>
|
||||
<div className="anim-collapse-inner">
|
||||
<div className="card" style={{ padding: 12, overflowX: 'auto' }}>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 12, flexWrap: 'wrap', marginBottom: 12 }}>
|
||||
<div>
|
||||
<div style={{ fontSize: 13, fontWeight: 600, color: 'var(--color-text-primary)' }}>最近调试追踪</div>
|
||||
@@ -1716,6 +1749,8 @@ export default function ProxyLogs() {
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{isMobile ? (
|
||||
<MobileDrawer
|
||||
|
||||
Reference in New Issue
Block a user