diff --git a/src/i18n/ja.ts b/src/i18n/ja.ts index c7b5e2c..c9ef84f 100644 --- a/src/i18n/ja.ts +++ b/src/i18n/ja.ts @@ -775,7 +775,7 @@ export const jaOverrides = { 'usage.analysis.shareLabel': '割合', 'usage.events.title': 'リクエストイベントログ', 'usage.events.description': '選択した期間のリクエストイベントを絞り込んで確認します。', - 'usage.events.columns': '列', + 'usage.events.columns': '表示する列', 'usage.events.exportPage': '絞り込み結果を CSV 出力', 'usage.events.exportDescription': '現在の絞り込み結果の全リクエスト項目を CSV ファイルに出力し、保存先を選択します', 'usage.events.exportDialogTitle': 'CSV の保存先を選択', @@ -789,6 +789,10 @@ export const jaOverrides = { 'usage.events.dragHint': 'ヘッダーの境界をドラッグして列幅を調整', 'usage.events.columnSettings': '表示設定', 'usage.events.columnSettingsDescription': 'リクエスト詳細に表示する列を選択します。', + 'usage.events.rowHeight.title': 'レコードの行高を固定', + 'usage.events.rowHeight.description': 'すべてのレコードを同じ高さにします。オフにすると内容に合わせて調整します。', + 'usage.events.rowHeight.fixed': '行高', + 'usage.events.rowHeight.dragHint': 'スライダーをドラッグして調整', 'usage.events.columnsSelected': '{total} 列中 {selected} 列を選択', 'usage.events.selectAllColumns': 'すべて選択', 'usage.events.applyColumns': '適用', diff --git a/src/i18n/locales/en.ts b/src/i18n/locales/en.ts index a9c9bbf..c427d28 100644 --- a/src/i18n/locales/en.ts +++ b/src/i18n/locales/en.ts @@ -763,7 +763,7 @@ export const en: Record = { 'usage.analysis.shareLabel': 'Share', 'usage.events.title': 'Request Event Log', 'usage.events.description': 'Filter and inspect request events in the selected time range.', - 'usage.events.columns': 'Columns', + 'usage.events.columns': 'Show columns', 'usage.events.exportPage': 'Export Filtered CSV', 'usage.events.exportDescription': 'Export all request fields matching the current filters and choose where to save the CSV', 'usage.events.exportDialogTitle': 'Choose where to save the CSV', @@ -777,6 +777,10 @@ export const en: Record = { 'usage.events.dragHint': 'Drag column header borders to resize', 'usage.events.columnSettings': 'Display Settings', 'usage.events.columnSettingsDescription': 'Choose which columns appear in request details.', + 'usage.events.rowHeight.title': 'Fixed row height', + 'usage.events.rowHeight.description': 'Use one height for every record; turn it off to fit content automatically.', + 'usage.events.rowHeight.fixed': 'Row height', + 'usage.events.rowHeight.dragHint': 'Drag the slider to adjust', 'usage.events.columnsSelected': '{selected} of {total} columns selected', 'usage.events.selectAllColumns': 'Select All', 'usage.events.applyColumns': 'Apply', diff --git a/src/i18n/locales/zh-CN.ts b/src/i18n/locales/zh-CN.ts index d74ed72..70221e2 100644 --- a/src/i18n/locales/zh-CN.ts +++ b/src/i18n/locales/zh-CN.ts @@ -762,7 +762,7 @@ export const zhCN = { 'usage.analysis.shareLabel': '占比', 'usage.events.title': '请求事件日志', 'usage.events.description': '筛选并查看所选时间范围内的请求事件。', - 'usage.events.columns': '列', + 'usage.events.columns': '显示列', 'usage.events.exportPage': '导出筛选结果 CSV', 'usage.events.exportDescription': '导出当前筛选结果中的全部请求字段,并选择保存位置', 'usage.events.exportDialogTitle': '选择 CSV 保存位置', @@ -776,6 +776,10 @@ export const zhCN = { 'usage.events.dragHint': '可拖动表头边线调整每列宽度', 'usage.events.columnSettings': '显示设置', 'usage.events.columnSettingsDescription': '选择请求明细中需要显示的列。', + 'usage.events.rowHeight.title': '固定记录行高', + 'usage.events.rowHeight.description': '开启后每条记录使用统一高度;关闭时根据内容自动适应。', + 'usage.events.rowHeight.fixed': '行高', + 'usage.events.rowHeight.dragHint': '拖动滑块调整高度', 'usage.events.columnsSelected': '已选择 {selected} / {total} 列', 'usage.events.selectAllColumns': '选择全部', 'usage.events.applyColumns': '应用', diff --git a/src/pages/UsageEventsView.css b/src/pages/UsageEventsView.css index 5800fb8..75ac077 100644 --- a/src/pages/UsageEventsView.css +++ b/src/pages/UsageEventsView.css @@ -50,16 +50,20 @@ background: var(--usage-log-surface); color: var(--usage-log-muted); box-shadow: none; - font-size: 11px; + font-size: 12px; font-weight: 500; white-space: nowrap; cursor: pointer; transition: background .15s ease, border-color .15s ease; } -.usage-request-log .usage-col-reset-btn.icon-only { - width: 32px; - padding: 0; +.usage-request-log .usage-col-settings-btn svg { + width: 16px; + height: 16px; +} + +.usage-request-log .usage-col-settings-btn { + color: var(--usage-log-text); } .usage-request-log .usage-col-settings-btn:hover, @@ -131,6 +135,14 @@ line-height: 1.45; } +.usage-request-log.usage-row-height-auto .usage-events-table td { + height: auto; +} + +.usage-request-log.usage-row-height-fixed .usage-events-table td { + height: var(--usage-row-height, 68px); +} + .usage-request-log .usage-events-table tbody tr:hover td { background: var(--usage-log-hover) !important; } diff --git a/src/pages/UsageEventsView.tsx b/src/pages/UsageEventsView.tsx index 79075e3..95a678f 100644 --- a/src/pages/UsageEventsView.tsx +++ b/src/pages/UsageEventsView.tsx @@ -1,8 +1,8 @@ import { usagePreferences } from '../services/usagePreferences'; -import { useEffect, useRef, useState, type KeyboardEvent } from 'react'; +import { useEffect, useRef, useState, type KeyboardEvent, type CSSProperties } from 'react'; import { invoke } from '@tauri-apps/api/core'; import { save } from '@tauri-apps/plugin-dialog'; -import { ArrowDown, ArrowUp, Brain, ChevronLeft, ChevronRight, Columns3Cog, Database, DatabaseZap, Download, RotateCcw, TriangleAlert, X } from 'lucide-react'; +import { ArrowDown, ArrowUp, Brain, ChevronLeft, ChevronRight, Columns3, Database, DatabaseZap, Download, RotateCcw, TriangleAlert, X } from 'lucide-react'; import { getCurrentLocale, useI18n } from '../i18n'; import type { MessageKey } from '../i18n/resources'; import { formatCacheReadRate, formatGenerationSpeed } from '../services/usageMetrics'; @@ -116,9 +116,26 @@ const EVENT_COL_WIDTHS_STORAGE_KEY = 'cpa-gui.usage-events-col-widths.v4'; const LEGACY_EVENT_COL_WIDTHS_STORAGE_KEY = 'cpa-gui.usage-events-col-widths.v3'; const EVENT_VISIBLE_COLS_STORAGE_KEY = 'cpa-gui.usage-events-visible-cols.v6'; const LEGACY_EVENT_VISIBLE_COLS_STORAGE_KEY = 'cpa-gui.usage-events-visible-cols.v5'; +const EVENT_ROW_HEIGHT_ENABLED_STORAGE_KEY = 'cpa-gui.usage-events-row-height-enabled.v1'; +const EVENT_ROW_HEIGHT_STORAGE_KEY = 'cpa-gui.usage-events-row-height.v1'; +const DEFAULT_EVENT_ROW_HEIGHT = 68; +const MIN_EVENT_ROW_HEIGHT = 48; +const MAX_EVENT_ROW_HEIGHT = 140; const getAllEventColumnKeys = () => EVENT_COLUMNS.map((column) => column.key); +const clampEventRowHeight = (value: number) => Math.min( + MAX_EVENT_ROW_HEIGHT, + Math.max(MIN_EVENT_ROW_HEIGHT, Math.round(value)), +); + +const getInitialRowHeightEnabled = () => usagePreferences.getItem(EVENT_ROW_HEIGHT_ENABLED_STORAGE_KEY) === 'true'; + +const getInitialRowHeight = () => { + const value = Number(usagePreferences.getItem(EVENT_ROW_HEIGHT_STORAGE_KEY)); + return Number.isFinite(value) ? clampEventRowHeight(value) : DEFAULT_EVENT_ROW_HEIGHT; +}; + export const getInitialVisibleColumns = (): EventColumnKey[] => { try { const currentRaw = usagePreferences.getItem(EVENT_VISIBLE_COLS_STORAGE_KEY); @@ -480,6 +497,8 @@ export function EventsView({ const [columnSettingsOpen, setColumnSettingsOpen] = useState(false); const [draftVisibleColumnKeys, setDraftVisibleColumnKeys] = useState(visibleColumnKeys); const [resizingCol, setResizingCol] = useState(null); + const [fixedRowHeight, setFixedRowHeight] = useState(getInitialRowHeightEnabled); + const [rowHeight, setRowHeight] = useState(getInitialRowHeight); const [exporting, setExporting] = useState(false); const columnDialogRef = useDialogFocusTrap({ @@ -543,6 +562,17 @@ export function EventsView({ setDraftVisibleColumnKeys(getAllEventColumnKeys()); }; + const updateFixedRowHeight = (enabled: boolean) => { + setFixedRowHeight(enabled); + usagePreferences.setItem(EVENT_ROW_HEIGHT_ENABLED_STORAGE_KEY, String(enabled)); + }; + + const updateRowHeight = (value: number) => { + const next = clampEventRowHeight(value); + setRowHeight(next); + usagePreferences.setItem(EVENT_ROW_HEIGHT_STORAGE_KEY, String(next)); + }; + const resetSingleColumn = (key: EventColumnKey, e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); @@ -686,12 +716,12 @@ export function EventsView({ }; return ( -
+
{loading && events.items.length === 0 ?
: events.items.length ? (
{visibleColumns.map((col) => ( @@ -769,19 +799,22 @@ export function EventsView({ onClick={openColumnSettings} title={t('usage.events.columnSettings')} aria-label={t('usage.events.columnSettings')} + aria-haspopup="dialog" + aria-expanded={columnSettingsOpen} > -