@@ -9,6 +9,12 @@ const { onUpdate, offUpdate, reset, copy, getLog } = useLogStore();
99const { log } = storeToRefs (useLogStore ());
1010const { version } = useAppInfo ();
1111
12+ // Filter states
13+ const selectedLevels = ref <string []>([]);
14+
15+ // Log levels
16+ const logLevels = [' INFO' , ' WARNING' , ' ERROR' , ' DEBUG' ];
17+
1218const formatLog = computed (() => {
1319 const list = log .value
1420 .trim ()
@@ -30,6 +36,31 @@ const formatLog = computed(() => {
3036 });
3137});
3238
39+ // Filtered logs based on selected levels
40+ const filteredLog = computed (() => {
41+ if (selectedLevels .value .length === 0 ) {
42+ return formatLog .value ;
43+ }
44+ return formatLog .value .filter ((entry ) =>
45+ selectedLevels .value .includes (entry .type )
46+ );
47+ });
48+
49+ // Toggle level filter
50+ function toggleLevel(level : string ) {
51+ const index = selectedLevels .value .indexOf (level );
52+ if (index === - 1 ) {
53+ selectedLevels .value .push (level );
54+ } else {
55+ selectedLevels .value .splice (index , 1 );
56+ }
57+ }
58+
59+ // Clear all filters
60+ function clearFilters() {
61+ selectedLevels .value = [];
62+ }
63+
3364function typeColor(type : string ) {
3465 const M: Record <string , string > = {
3566 INFO: ' var(--color-primary)' ,
@@ -74,9 +105,38 @@ onDeactivated(() => {
74105 <div class =" page-log" >
75106 <div class =" log-layout" >
76107 <ab-container :title =" $t('log.title')" class =" log-main" >
108+ <!-- Level Filter Section -->
109+ <div class =" log-filters" >
110+ <div class =" filter-group" >
111+ <span class =" filter-label" >{{ $t('log.filter_level') }}</span >
112+ <div class =" filter-chips" >
113+ <button
114+ v-for =" level in logLevels"
115+ :key =" level"
116+ class =" filter-chip"
117+ :class =" {
118+ active: selectedLevels.includes(level),
119+ [`level-${level.toLowerCase()}`]: true,
120+ }"
121+ @click =" toggleLevel(level)"
122+ >
123+ {{ level }}
124+ </button >
125+ </div >
126+ </div >
127+
128+ <button
129+ v-if =" selectedLevels.length > 0"
130+ class =" clear-filters"
131+ @click =" clearFilters"
132+ >
133+ {{ $t('log.clear_filters') }}
134+ </button >
135+ </div >
136+
77137 <div ref =" logContainer" class =" log-viewer" >
78138 <div class =" log-content" >
79- <template v-for =" i in formatLog " :key =" i .index " >
139+ <template v-for =" i in filteredLog " :key =" i .index " >
80140 <div
81141 class =" log-entry"
82142 :style =" { color: typeColor(i.type) }"
@@ -252,6 +312,117 @@ onDeactivated(() => {
252312 font-size : 13px ;
253313}
254314
315+ .log-filters {
316+ display : flex ;
317+ flex-direction : column ;
318+ gap : 12px ;
319+ margin-bottom : 12px ;
320+ padding-bottom : 12px ;
321+ border-bottom : 1px solid var (--color-border );
322+ }
323+
324+ .filter-group {
325+ display : flex ;
326+ flex-direction : column ;
327+ gap : 8px ;
328+
329+ @include forDesktop {
330+ flex-direction : row ;
331+ align-items : center ;
332+ }
333+ }
334+
335+ .filter-label {
336+ font-size : 13px ;
337+ font-weight : 500 ;
338+ color : var (--color-text-muted );
339+ min-width : 60px ;
340+ }
341+
342+ .filter-chips {
343+ display : flex ;
344+ flex-wrap : wrap ;
345+ gap : 6px ;
346+ }
347+
348+ .filter-chip {
349+ padding : 4px 12px ;
350+ border-radius : var (--radius-sm );
351+ border : 1px solid var (--color-border );
352+ background : transparent ;
353+ font-size : 12px ;
354+ cursor : pointer ;
355+ transition : all var (--transition-fast );
356+ color : var (--color-text );
357+
358+ & :hover {
359+ border-color : var (--color-primary );
360+ }
361+
362+ & .active {
363+ background : var (--color-primary );
364+ border-color : var (--color-primary );
365+ color : white ;
366+ }
367+
368+ & .level-info {
369+ & :hover ,
370+ & .active {
371+ border-color : var (--color-primary );
372+ }
373+ & .active {
374+ background : var (--color-primary );
375+ }
376+ }
377+
378+ & .level-warning {
379+ & :hover ,
380+ & .active {
381+ border-color : var (--color-warning );
382+ }
383+ & .active {
384+ background : var (--color-warning );
385+ }
386+ }
387+
388+ & .level-error {
389+ & :hover ,
390+ & .active {
391+ border-color : var (--color-danger );
392+ }
393+ & .active {
394+ background : var (--color-danger );
395+ }
396+ }
397+
398+ & .level-debug {
399+ & :hover ,
400+ & .active {
401+ border-color : var (--color-text-muted );
402+ }
403+ & .active {
404+ background : var (--color-text-muted );
405+ }
406+ }
407+ }
408+
409+ .clear-filters {
410+ align-self : flex-start ;
411+ padding : 4px 12px ;
412+ border-radius : var (--radius-sm );
413+ border : none ;
414+ background : var (--color-danger-light );
415+ color : var (--color-danger );
416+ font-size : 12px ;
417+ cursor : pointer ;
418+ transition : all var (--transition-fast );
419+
420+ & :hover {
421+ background : var (--color-danger );
422+ color : white ;
423+ }
424+ }
425+
255426.log-actions {
256427 display : flex ;
257428 justify-content : flex-end ;
0 commit comments