- Extend GET /api/v1/logs with cursor pagination, multi-level filtering, optional application scoping, and level count aggregation - Add exchangeId, instanceId, application, mdc fields to log responses - Refactor ClickHouseLogStore with keyset pagination (N+1 pattern) - Add LogSearchRequest/LogSearchResponse core domain records - Create LogSearchPageResponse wrapper DTO - Add Logs as 4th content tab (Exchanges | Dashboard | Runtime | Logs) - Implement LogSearch component with debounced search, level filter bar, expandable log entries, cursor pagination, and live tail mode - Add cross-navigation: exchange header → logs, log tab → logs tab - Update ClickHouseLogStoreIT with cursor, multi-level, cross-app tests Closes: #104 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
31 lines
767 B
TypeScript
31 lines
767 B
TypeScript
import { Tabs } from '@cameleer/design-system';
|
|
import type { TabKey, Scope } from '../hooks/useScope';
|
|
import { TabKpis } from './TabKpis';
|
|
import styles from './ContentTabs.module.css';
|
|
|
|
const TABS = [
|
|
{ label: 'Exchanges', value: 'exchanges' },
|
|
{ label: 'Dashboard', value: 'dashboard' },
|
|
{ label: 'Runtime', value: 'runtime' },
|
|
{ label: 'Logs', value: 'logs' },
|
|
];
|
|
|
|
interface ContentTabsProps {
|
|
active: TabKey;
|
|
onChange: (tab: TabKey) => void;
|
|
scope: Scope;
|
|
}
|
|
|
|
export function ContentTabs({ active, onChange, scope }: ContentTabsProps) {
|
|
return (
|
|
<div className={styles.wrapper}>
|
|
<Tabs
|
|
tabs={TABS}
|
|
active={active}
|
|
onChange={(v) => onChange(v as TabKey)}
|
|
/>
|
|
<TabKpis scope={scope} />
|
|
</div>
|
|
);
|
|
}
|