1
1
<template >
2
- <div class =" ml-3" >
3
- <!-- Button to audit multiple findings -->
4
- <!-- Audit Modal -->
5
- <AuditModal
6
- ref =" auditModal"
7
- :selectedCheckBoxIds =" selectedCheckBoxIds"
8
- @update-audit =" updateAudit"
9
- />
10
- <!-- Column Modal -->
11
- <ColumnSelector ref =" columnModal" @update-columns =" setTableFields" />
12
- </div >
2
+ <AuditModal
3
+ ref =" auditModal"
4
+ :selectedCheckBoxIds =" selectedCheckBoxIds"
5
+ @update-audit =" updateAudit"
6
+ />
7
+ <ColumnSelector ref =" columnModal" @update-columns =" setTableFields" />
13
8
14
9
<div class =" py-3" >
15
10
<BTable
16
11
ref =" auditTable"
17
12
id =" rule-analysis-table"
18
- :items =" findingList "
13
+ :items =" filteredList "
19
14
:fields =" fields as TableField[]"
20
15
:current-page =" 1"
21
16
:per-page =" 0"
29
24
:caption-top =" true"
30
25
>
31
26
<template #table-caption >
32
- <BButton
33
- class =" d-inline-block me-3"
34
- variant =" primary"
35
- size =" sm"
36
- id =" AuditButton"
37
- v-on:click =" showAuditModal()"
38
- :disabled =" auditButtonDisabled"
39
- >AUDIT</BButton
40
- >
41
- <BButton
42
- class =" d-inline-block"
43
- variant =" primary"
44
- size =" sm"
45
- id =" AuditButton"
46
- v-on:click =" showColumnSelect()"
47
- >Columns</BButton
48
- >
27
+ <div class =" row me-0 mr-0" >
28
+ <div class =" col-md-4" >
29
+ <BButton
30
+ class =" d-inline-block me-3"
31
+ variant =" primary"
32
+ size =" sm"
33
+ id =" AuditButton"
34
+ v-on:click =" showAuditModal()"
35
+ :disabled =" auditButtonDisabled"
36
+ >AUDIT</BButton
37
+ >
38
+ <BButton
39
+ class =" d-inline-block"
40
+ variant =" primary"
41
+ size =" sm"
42
+ id =" AuditButton"
43
+ v-on:click =" showColumnSelect()"
44
+ >Columns</BButton
45
+ >
46
+ </div >
47
+ <div class =" col-md-4" >
48
+ <BFormInput
49
+ class =" hover-opacity"
50
+ id =" filter-files"
51
+ placeholder =" filename"
52
+ v-model =" filterString"
53
+ :required =" true"
54
+ />
55
+ </div >
56
+ </div >
49
57
</template >
50
58
51
59
<!-- Select all checkboxes -->
@@ -129,6 +137,7 @@ import {
129
137
BButton ,
130
138
type TableField ,
131
139
type TableItem ,
140
+ BFormInput ,
132
141
} from ' bootstrap-vue-next' ;
133
142
import { FontAwesomeIcon } from ' @fortawesome/vue-fontawesome' ;
134
143
import FindingsService from ' @/services/findings-service' ;
@@ -153,6 +162,7 @@ const props = defineProps<Props>();
153
162
const auditModal = ref ();
154
163
const columnModal = ref ();
155
164
const auditTable = ref ();
165
+ const filterString = ref (' ' );
156
166
157
167
const findingList = ref (props .findings as TableItemDetailedFindingRead []);
158
168
const selectedCheckBoxIds = ref ([] as number []);
@@ -164,6 +174,36 @@ const selectedIndex = ref(undefined as number | undefined);
164
174
const store = useAuthUserStore ();
165
175
const emit = defineEmits ([' refresh-table' ]);
166
176
177
+ // Simple filter function
178
+ // if start with * we check the ending of the file path.
179
+ // if end with * we check the beginning of the file path.
180
+ // if does not contain * we only check if the needle is in the string.
181
+ function applyFilter() {
182
+ if (filterString .value === ' ' ) {
183
+ return findingList .value ;
184
+ }
185
+
186
+ const token = filterString .value ;
187
+
188
+ if (token .startsWith (' *' )) {
189
+ return findingList .value .filter ((finding ) => {
190
+ return finding .file_path .endsWith (token .substring (1 ));
191
+ });
192
+ }
193
+
194
+ if (token .endsWith (' *' )) {
195
+ return findingList .value .filter ((finding ) => {
196
+ return finding .file_path .startsWith (token .substring (0 , token .length - 1 ));
197
+ });
198
+ }
199
+
200
+ return findingList .value .filter ((finding ) => {
201
+ return finding .file_path .includes (token );
202
+ });
203
+ }
204
+
205
+ const filteredList = computed (applyFilter );
206
+
167
207
function setTableFields(selectedColumns : TableColumn [] = []) {
168
208
// @ts-ignore ignore TS2589
169
209
fields .value = ColumnUtils .getColumns (selectedColumns , store .tableColumns , props .is_rule_finding );
@@ -178,7 +218,7 @@ function selectSingleCheckbox() {
178
218
function selectAllCheckboxes() {
179
219
selectedCheckBoxIds .value = [];
180
220
if (allSelected .value ) {
181
- for (const finding of findingList .value ) {
221
+ for (const finding of filteredList .value ) {
182
222
selectedCheckBoxIds .value .push (finding .id_ );
183
223
}
184
224
}
@@ -188,7 +228,7 @@ function toggleAllCheckboxes() {
188
228
selectedCheckBoxIds .value = [];
189
229
allSelected .value = ! allSelected .value ;
190
230
if (allSelected .value ) {
191
- for (const finding of findingList .value ) {
231
+ for (const finding of filteredList .value ) {
192
232
selectedCheckBoxIds .value .push (finding .id_ );
193
233
}
194
234
}
@@ -243,14 +283,14 @@ function getCurrentFindingSelected(): TableItemDetailedFindingRead | undefined {
243
283
return undefined ;
244
284
}
245
285
246
- return findingList .value [selectedIndex .value ];
286
+ return filteredList .value [selectedIndex .value ];
247
287
}
248
288
249
289
function selectDown(): boolean {
250
290
const detailsStatus = getCurrentFindingSelected ()?._showDetails ;
251
291
closeAllDetails ();
252
292
253
- selectedIndex .value = ((selectedIndex .value ?? - 1 ) + 1 ) % props . findings .length ;
293
+ selectedIndex .value = ((selectedIndex .value ?? - 1 ) + 1 ) % filteredList . value .length ;
254
294
auditTable .value .clearSelected ();
255
295
auditTable .value .selectRow (selectedIndex .value );
256
296
@@ -444,3 +484,21 @@ watch(
444
484
},
445
485
);
446
486
</script >
487
+ <style lang="scss">
488
+ .hover-opacity {
489
+ opacity : 0 ;
490
+ transition : all 0.2s ease-in-out !important ;
491
+
492
+ & :hover {
493
+ opacity : 1 ;
494
+ }
495
+
496
+ & :focus {
497
+ opacity : 1 ;
498
+ }
499
+ }
500
+
501
+ input .hover-opacity :valid {
502
+ opacity : 1 ;
503
+ }
504
+ </style >
0 commit comments