make proxy trace panel collapsible (#327)

This commit is contained in:
Cita
2026-03-30 16:32:26 +08:00
committed by GitHub
parent 26d87db2cb
commit 0d2c4501c2
2 changed files with 229 additions and 126 deletions
@@ -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 () => { it('opens debug trace detail on demand instead of preloading the first trace inline', async () => {
let root!: WebTestRenderer; let root!: WebTestRenderer;
+36 -1
View File
@@ -622,6 +622,7 @@ export default function ProxyLogs() {
const [showDebugSettingsModal, setShowDebugSettingsModal] = useState(false); const [showDebugSettingsModal, setShowDebugSettingsModal] = useState(false);
const [debugPanelLoading, setDebugPanelLoading] = useState(false); const [debugPanelLoading, setDebugPanelLoading] = useState(false);
const [debugPanelSaving, setDebugPanelSaving] = useState(false); const [debugPanelSaving, setDebugPanelSaving] = useState(false);
const [debugTracePanelExpanded, setDebugTracePanelExpanded] = useState(true);
const [debugSettings, setDebugSettings] = useState<ProxyDebugSettingsState>(DEFAULT_PROXY_DEBUG_SETTINGS); const [debugSettings, setDebugSettings] = useState<ProxyDebugSettingsState>(DEFAULT_PROXY_DEBUG_SETTINGS);
const [debugDraftSettings, setDebugDraftSettings] = useState<ProxyDebugSettingsState>(DEFAULT_PROXY_DEBUG_SETTINGS); const [debugDraftSettings, setDebugDraftSettings] = useState<ProxyDebugSettingsState>(DEFAULT_PROXY_DEBUG_SETTINGS);
const [debugTraces, setDebugTraces] = useState<ProxyDebugTraceListItem[]>([]); const [debugTraces, setDebugTraces] = useState<ProxyDebugTraceListItem[]>([]);
@@ -994,6 +995,9 @@ export default function ProxyLogs() {
const updated = await api.updateRuntimeSettings(buildProxyDebugSettingsPayload(nextSettings)); const updated = await api.updateRuntimeSettings(buildProxyDebugSettingsPayload(nextSettings));
const normalized = normalizeProxyDebugSettings(updated); const normalized = normalizeProxyDebugSettings(updated);
applyLoadedDebugSettings(normalized, { syncDraft: true }); applyLoadedDebugSettings(normalized, { syncDraft: true });
if (normalized.proxyDebugTraceEnabled) {
setDebugTracePanelExpanded(true);
}
if (options?.closeAfterSave) { if (options?.closeAfterSave) {
setShowDebugSettingsModal(false); setShowDebugSettingsModal(false);
} }
@@ -1542,6 +1546,29 @@ export default function ProxyLogs() {
</div> </div>
</div> </div>
<div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}> <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 <button
type="button" type="button"
className={debugSettings.proxyDebugTraceEnabled ? 'btn btn-ghost btn-ghost-active' : 'btn btn-ghost'} className={debugSettings.proxyDebugTraceEnabled ? 'btn btn-ghost btn-ghost-active' : 'btn btn-ghost'}
@@ -1586,7 +1613,13 @@ export default function ProxyLogs() {
</div> </div>
</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 style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 12, flexWrap: 'wrap', marginBottom: 12 }}>
<div> <div>
<div style={{ fontSize: 13, fontWeight: 600, color: 'var(--color-text-primary)' }}>最近调试追踪</div> <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--color-text-primary)' }}>最近调试追踪</div>
@@ -1716,6 +1749,8 @@ export default function ProxyLogs() {
</div> </div>
) : null} ) : null}
</div> </div>
</div>
</div>
{isMobile ? ( {isMobile ? (
<MobileDrawer <MobileDrawer