|
2 | 2 | <div class="h3 mb-4">{{ $t('Comments') }}</div> |
3 | 3 | <CommentsFilterForm class="mb-4" v-model="filters" /> |
4 | 4 | <VTableServer :items="comments" :itemsLength="comments.length" :is-loading="commentsIsLoading"> |
5 | | - <VColumn :header="$t('Id')" field="id" /> |
6 | | - <VColumn :header="$t('Name')" field="name" /> |
| 5 | + <VColumn :header="$t('Id')" field="id"> |
| 6 | + <template #body="{ item }"> |
| 7 | + <span v-html="highlightText(item.id)" /> |
| 8 | + </template> |
| 9 | + </VColumn> |
| 10 | + <VColumn :header="$t('Name')" field="name"> |
| 11 | + <template #body="{ item }"> |
| 12 | + <span v-html="highlightText(item.name)" /> |
| 13 | + </template> |
| 14 | + </VColumn> |
7 | 15 | <VColumn :header="$t('Email')" field="email" /> |
8 | 16 | <VColumn :header="$t('Post')" field="postId"> |
9 | 17 | <template #body> |
|
12 | 20 | </button> |
13 | 21 | </template> |
14 | 22 | </VColumn> |
15 | | - <VColumn :header="$t('Text')" field="body" /> |
| 23 | + <VColumn :header="$t('Text')" field="body"> |
| 24 | + <template #body="{ item }"> |
| 25 | + <span v-html="highlightText(item.body)" /> |
| 26 | + </template> |
| 27 | + </VColumn> |
16 | 28 | <VColumn :header="$t('Status')" field="id"> |
17 | 29 | <template #body="{ item }"> |
18 | 30 | <span v-if="item.status === 'PENDING'"> |
@@ -65,23 +77,37 @@ export default { |
65 | 77 |
|
66 | 78 | const filteredComments = computed(() => { |
67 | 79 | const enteredEmail = filters?.email && filters.email.trim().toLowerCase(); |
68 | | - const query = filters?.searchQuery && isNaN(Number(filters.querySearch)) ? filters.searchQuery.trim().toLowerCase() : undefined; |
| 80 | + const query = filters?.searchQuery && isNaN(Number(filters.searchQuery)) ? filters.searchQuery.trim().toLowerCase() : filters.searchQuery; |
69 | 81 | const status = filters?.status && filters.status.trim(); |
70 | 82 |
|
71 | 83 | const matchesEmail = (email) => enteredEmail && email.trim().toLowerCase().includes(enteredEmail) |
72 | | - const matchesQuery = (id,body,name)=> id=== Number(query) || body.trim().toLowerCase().includes(query) || name.trim().toLowerCase().includes(query) |
| 84 | + const matchesQuery = (id, body, name) => id === Number(query) || body.trim().toLowerCase().includes(query) || name.trim().toLowerCase().includes(query) |
73 | 85 |
|
74 | 86 | return comments.value?.filter(comment => { |
75 | | - if(!query && !enteredEmail && !status) return true; |
| 87 | + if (!query && !enteredEmail && !status) return true; |
76 | 88 | return matchesEmail(comment.email) || matchesQuery(comment.id, comment.body, comment.name) || status === comment.status; |
77 | 89 | }); |
78 | 90 | }); |
79 | 91 |
|
| 92 | + const highlightText = (text) => { |
| 93 | + const query = filters?.searchQuery && isNaN(Number(filters.searchQuery)) ? filters.searchQuery.trim().toLowerCase() : undefined; |
| 94 | + if (!query) return text; |
| 95 | + |
| 96 | + const indexOfQuery = String(text).toLowerCase().indexOf(query); |
| 97 | + if (indexOfQuery === -1) return text; |
80 | 98 |
|
| 99 | + const originalText = String(text) |
| 100 | + const prefix = originalText.slice(0, indexOfQuery); |
| 101 | + const matchPart = originalText.slice(indexOfQuery, indexOfQuery + query.length); |
| 102 | + const suffix = originalText.slice(indexOfQuery + query.length); |
| 103 | + return `${prefix}<mark class="border">${matchPart}</mark>${suffix}`; |
| 104 | +
|
| 105 | + } |
81 | 106 | return { |
82 | 107 | comments: filteredComments, |
83 | 108 | commentsIsLoading, |
84 | | - filters |
| 109 | + filters, |
| 110 | + highlightText |
85 | 111 | } |
86 | 112 | }, |
87 | 113 | components: { |
|
0 commit comments