11import React , { useState , useEffect , useCallback } from 'react' ;
22import { Settings , Zap , Eye , ChevronDown , ChevronUp , Target , Code , ZoomIn } from 'lucide-react' ;
3+ import { METRIC_PRESETS } from '../metricPresets.js' ;
34
45// 匹配模式枚举
56const MATCH_MODES = {
@@ -23,6 +24,17 @@ const MODE_CONFIG = {
2324 }
2425} ;
2526
27+ // 根据配置生成友好的标题
28+ function getMetricTitle ( metric , index ) {
29+ if ( metric . name && metric . name . trim ( ) ) return metric . name . trim ( ) ;
30+ if ( metric . keyword ) return metric . keyword . replace ( / [: : ] / g, '' ) . trim ( ) ;
31+ if ( metric . regex ) {
32+ const sanitized = metric . regex . replace ( / [ ^ a - z A - Z 0 - 9 _ ] / g, '' ) . trim ( ) ;
33+ return sanitized || `Metric ${ index + 1 } ` ;
34+ }
35+ return `Metric ${ index + 1 } ` ;
36+ }
37+
2638// 数值提取器类
2739export class ValueExtractor {
2840 // 关键词匹配
@@ -215,7 +227,7 @@ export function RegexControls({
215227 if ( file . content ) {
216228 globalParsingConfig . metrics . forEach ( ( cfg , idx ) => {
217229 const matches = extractValues ( file . content , cfg . mode , cfg ) ;
218- const key = cfg . name || `metric ${ idx + 1 } ` ;
230+ const key = getMetricTitle ( cfg , idx ) ;
219231 if ( ! results [ key ] ) results [ key ] = [ ] ;
220232 results [ key ] . push ( {
221233 fileName : file . name ,
@@ -299,13 +311,21 @@ export function RegexControls({
299311 onGlobalParsingConfigChange ( { metrics : newMetrics } ) ;
300312 } ;
301313
314+ const applyPreset = ( index , presetLabel ) => {
315+ const preset = METRIC_PRESETS . find ( p => p . label === presetLabel ) ;
316+ if ( ! preset ) return ;
317+ const newMetrics = [ ...globalParsingConfig . metrics ] ;
318+ newMetrics [ index ] = { ...newMetrics [ index ] , ...preset } ;
319+ onGlobalParsingConfigChange ( { metrics : newMetrics } ) ;
320+ } ;
321+
302322 const handleXRangeChange = ( field , value ) => {
303323 const newRange = { ...xRange , [ field ] : value === '' ? undefined : Number ( value ) } ;
304324 onXRangeChange ( newRange ) ;
305325 } ;
306326
307327 // 渲染配置项的函数
308- const renderConfigPanel = ( type , config , onConfigChange ) => {
328+ const renderConfigPanel = ( type , config , onConfigChange , index ) => {
309329 const ModeIcon = MODE_CONFIG [ config . mode ] . icon ;
310330
311331 return (
@@ -318,6 +338,16 @@ export function RegexControls({
318338 onChange = { ( e ) => onConfigChange ( 'name' , e . target . value ) }
319339 className = "w-full px-2 py-1 text-sm border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500 focus:outline-none"
320340 />
341+ < select
342+ onChange = { ( e ) => applyPreset ( index , e . target . value ) }
343+ className = "w-full px-2 py-1 text-xs border border-gray-300 rounded-md mt-1 focus:ring-2 focus:ring-blue-500 focus:border-blue-500 focus:outline-none"
344+ defaultValue = ""
345+ >
346+ < option value = "" > 选择预设</ option >
347+ { METRIC_PRESETS . map ( p => (
348+ < option key = { p . label } value = { p . label } > { p . label } </ option >
349+ ) ) }
350+ </ select >
321351 </ div >
322352 { /* 模式选择 */ }
323353 < div >
@@ -430,9 +460,9 @@ export function RegexControls({
430460 </ button >
431461 < h4 className = "text-sm font-medium text-gray-800 mb-2 flex items-center gap-1" >
432462 < span className = "w-3 h-3 bg-blue-500 rounded-full" > </ span >
433- { cfg . name || `Metric ${ idx + 1 } ` } 解析配置
463+ { getMetricTitle ( cfg , idx ) } 解析配置
434464 </ h4 >
435- { renderConfigPanel ( `metric-${ idx } ` , cfg , ( field , value ) => handleMetricChange ( idx , field , value ) ) }
465+ { renderConfigPanel ( `metric-${ idx } ` , cfg , ( field , value ) => handleMetricChange ( idx , field , value ) , idx ) }
436466 </ div >
437467 ) ) }
438468 < button
0 commit comments