11<script setup lang="ts">
22import { ExtendedFailedMessage } from " @/resources/FailedMessage" ;
33import CopyToClipboard from " @/components/CopyToClipboard.vue" ;
4- import { ref } from " vue" ;
4+ import { computed , ref } from " vue" ;
55const props = defineProps <{
66 message: ExtendedFailedMessage ;
77}>();
88
99const hoverStates = ref <Record <number , boolean >>({});
10-
10+ const searchTerm = ref < string >( " " );
1111const toggleHover = (index : number , state : boolean ) => {
1212 hoverStates .value [index ] = state ;
1313};
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+ });
1421 </script >
1522
1623<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" >
1836 <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" >
2038 <td nowrap =" nowrap" >{{ header.key }}</td >
2139 <td >
2240 <div class =" headercopy" @mouseover =" toggleHover(index, true)" @mouseleave =" toggleHover(index, false)" >
2341 <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" />
2543 </div >
2644 </td >
2745 </tr >
2846 </tbody >
2947 </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 >
3051 <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 >
3152</template >
3253
@@ -36,4 +57,35 @@ const toggleHover = (index: number, state: boolean) => {
3657 align-items : top ;
3758 gap : 0.4rem ;
3859}
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+ }
3991 </style >
0 commit comments