|
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