1
1
<script setup lang="ts">
2
2
import { ExtendedFailedMessage } from " @/resources/FailedMessage" ;
3
3
import CopyToClipboard from " @/components/CopyToClipboard.vue" ;
4
- import { ref } from " vue" ;
4
+ import { computed , ref } from " vue" ;
5
5
const props = defineProps <{
6
6
message: ExtendedFailedMessage ;
7
7
}>();
8
8
9
9
const hoverStates = ref <Record <number , boolean >>({});
10
-
10
+ const searchTerm = ref < string >( " " );
11
11
const toggleHover = (index : number , state : boolean ) => {
12
12
hoverStates .value [index ] = state ;
13
13
};
14
+ // Computed property to filter headers based on search term
15
+ const filteredHeaders = computed (() => {
16
+ if (! searchTerm .value ) {
17
+ return props .message .headers ;
18
+ }
19
+ return props .message .headers .filter ((header ) => header .key .toLowerCase ().includes (searchTerm .value .toLowerCase ()) || header .value ?.toLowerCase ().includes (searchTerm .value .toLowerCase ()));
20
+ });
14
21
</script >
15
22
16
23
<template >
17
- <table class =" table" v-if =" !props.message.headersNotFound" >
24
+ <div >
25
+ <div class =" row filters" >
26
+ <div class =" col" >
27
+ <div class =" text-search-container" >
28
+ <div class =" text-search" >
29
+ <input type =" search" aria-label =" Filter by name" v-model =" searchTerm" class =" form-control format-text" placeholder =" Search for a header key or value..." />
30
+ </div >
31
+ </div >
32
+ </div >
33
+ </div >
34
+ </div >
35
+ <table class =" table" v-if =" filteredHeaders.length > 0 && !props.message.headersNotFound" >
18
36
<tbody >
19
- <tr class =" interactiveList" v-for =" (header, index) in props.message.headers " :key =" index" >
37
+ <tr class =" interactiveList" v-for =" (header, index) in filteredHeaders " :key =" index" >
20
38
<td nowrap =" nowrap" >{{ header.key }}</td >
21
39
<td >
22
40
<div class =" headercopy" @mouseover =" toggleHover(index, true)" @mouseleave =" toggleHover(index, false)" >
23
41
<pre >{{ header.value }}</pre >
24
- <CopyToClipboard v-if =" hoverStates[index]" :value =" header.value || '' " :isIconOnly =" true" />
42
+ <CopyToClipboard v-if =" hoverStates[index] && header.value " :value =" header.value" :isIconOnly =" true" />
25
43
</div >
26
44
</td >
27
45
</tr >
28
46
</tbody >
29
47
</table >
48
+
49
+ <!-- Message if filtered list is empty -->
50
+ <div v-if =" filteredHeaders.length <= 0 && !props.message.headersNotFound" class =" alert alert-warning" >No headers found matching the search term.</div >
30
51
<div v-if =" props.message.headersNotFound" class =" alert alert-info" >Could not find message headers. This could be because the message URL is invalid or the corresponding message was processed and is no longer tracked by ServiceControl.</div >
31
52
</template >
32
53
@@ -36,4 +57,35 @@ const toggleHover = (index: number, state: boolean) => {
36
57
align-items : top ;
37
58
gap : 0.4rem ;
38
59
}
60
+
61
+ /* empty filtered list message */
62
+ .alert-warning {
63
+ margin-top : 10px ;
64
+ color : #856404 ;
65
+ background-color : #fff3cd ;
66
+ border-color : #ffeeba ;
67
+ padding : 10px ;
68
+ border-radius : 5px ;
69
+ }
70
+
71
+ .text-search-container {
72
+ display : flex ;
73
+ flex-direction : row ;
74
+ }
75
+ .text-search {
76
+ width : 100% ;
77
+ max-width : 40rem ;
78
+ }
79
+ .format-text {
80
+ font-weight : unset ;
81
+ font-size : 14px ;
82
+ min-width : 120px ;
83
+ }
84
+ .filters {
85
+ background-color : #f3f3f3 ;
86
+ margin-top : 5px ;
87
+ border : #8c8c8c 1px solid ;
88
+ border-radius : 3px ;
89
+ padding : 5px ;
90
+ }
39
91
</style >
0 commit comments