@ouestfrance/sipa-bms-ui 8.6.0 → 8.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/form/BmsAutocomplete.vue.d.ts +2 -0
- package/dist/components/form/BmsInputBooleanCheckbox.vue.d.ts +1 -1
- package/dist/components/form/BmsInputCheckboxGroup.vue.d.ts +2 -2
- package/dist/components/form/BmsInputCode.vue.d.ts +2 -2
- package/dist/components/form/BmsInputNumber.vue.d.ts +2 -2
- package/dist/components/form/BmsInputRadio.vue.d.ts +2 -2
- package/dist/components/form/BmsInputText.vue.d.ts +24 -22
- package/dist/components/form/BmsMultiSelect.vue.d.ts +3 -1
- package/dist/components/form/BmsSearch.vue.d.ts +28 -24
- package/dist/components/form/BmsSelect.vue.d.ts +7 -17
- package/dist/components/form/RawAutocomplete.vue.d.ts +17 -21
- package/dist/components/form/RawInputText.vue.d.ts +9 -9
- package/dist/components/form/RawSelect.vue.d.ts +30 -0
- package/dist/components/navigation/UiTenantSwitcher.vue.d.ts +28 -24
- package/dist/components/table/BmsServerTable.vue.d.ts +18 -0
- package/dist/components/table/BmsTable.vue.d.ts +18 -1
- package/dist/components/table/BmsTableFilters.vue.d.ts +47 -25
- package/dist/composables/search.composable.d.ts +1 -0
- package/dist/plugins/field/FieldDatalist.vue.d.ts +2 -0
- package/dist/plugins/field/field-component.model.d.ts +2 -2
- package/dist/sipa-bms-ui.css +163 -116
- package/dist/sipa-bms-ui.es.js +725 -520
- package/dist/sipa-bms-ui.es.js.map +1 -1
- package/dist/sipa-bms-ui.umd.js +730 -525
- package/dist/sipa-bms-ui.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/components/form/BmsAutocomplete.vue +3 -0
- package/src/components/form/BmsInputNumber.spec.ts +26 -0
- package/src/components/form/BmsInputNumber.stories.js +20 -3
- package/src/components/form/BmsInputNumber.vue +36 -4
- package/src/components/form/BmsInputRadio.vue +1 -1
- package/src/components/form/BmsInputText.spec.ts +25 -0
- package/src/components/form/BmsInputText.stories.js +28 -3
- package/src/components/form/BmsInputText.vue +73 -12
- package/src/components/form/BmsMultiSelect.vue +66 -28
- package/src/components/form/BmsSelect.vue +60 -57
- package/src/components/form/RawAutocomplete.spec.ts +0 -8
- package/src/components/form/RawAutocomplete.vue +42 -24
- package/src/components/form/RawInputText.vue +14 -21
- package/src/components/form/RawSelect.vue +111 -0
- package/src/components/table/BmsServerTable.vue +18 -3
- package/src/components/table/BmsTable.vue +15 -2
- package/src/components/table/BmsTableFilters.vue +19 -7
- package/src/composables/search.composable.spec.ts +75 -0
- package/src/composables/search.composable.ts +54 -11
- package/src/plugins/field/FieldComponent.vue +6 -4
- package/src/plugins/field/FieldDatalist.stories.js +0 -9
- package/src/plugins/field/FieldDatalist.vue +16 -13
- package/src/plugins/field/field-component.model.ts +2 -2
- package/src/showroom/pages/autocomplete.vue +22 -1
- package/src/showroom/pages/server-table.vue +53 -22
- package/src/showroom/pages/table.vue +42 -3
- package/dist/plugins/field/FieldDatalist.spec.d.ts +0 -1
- package/src/plugins/field/FieldDatalist.spec.ts +0 -35
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
} from './search.composable';
|
|
7
7
|
import { defineComponent, nextTick } from 'vue';
|
|
8
8
|
import { mount } from '@vue/test-utils';
|
|
9
|
+
import { Filter } from '@/models';
|
|
9
10
|
|
|
10
11
|
vi.mock('vue-router', () => ({
|
|
11
12
|
useRoute: vi.fn(),
|
|
@@ -1292,5 +1293,79 @@ describe('search and filter composable', () => {
|
|
|
1292
1293
|
]);
|
|
1293
1294
|
});
|
|
1294
1295
|
});
|
|
1296
|
+
|
|
1297
|
+
describe('updateFiltersFromProps', () => {
|
|
1298
|
+
test('should update select options', () => {
|
|
1299
|
+
const wrapper = factory();
|
|
1300
|
+
const filter: Filter = {
|
|
1301
|
+
key: 'filter0',
|
|
1302
|
+
label: 'Zéro',
|
|
1303
|
+
type: 'select',
|
|
1304
|
+
selectOptions: [{ label: 'option1', value: '1' }],
|
|
1305
|
+
value: 1,
|
|
1306
|
+
};
|
|
1307
|
+
|
|
1308
|
+
wrapper.vm.filters = [filter];
|
|
1309
|
+
wrapper.vm.updateFiltersFromProps([{ ...filter, selectOptions: [] }]);
|
|
1310
|
+
expect(wrapper.vm.filters).toStrictEqual([
|
|
1311
|
+
{ ...filter, selectOptions: [], value: null },
|
|
1312
|
+
]);
|
|
1313
|
+
});
|
|
1314
|
+
|
|
1315
|
+
test('should not change filter other than options', () => {
|
|
1316
|
+
const wrapper = factory();
|
|
1317
|
+
const filter: Filter = {
|
|
1318
|
+
key: 'filter0',
|
|
1319
|
+
label: 'Zéro',
|
|
1320
|
+
type: 'select',
|
|
1321
|
+
selectOptions: [{ label: 'option1', value: '1' }],
|
|
1322
|
+
};
|
|
1323
|
+
|
|
1324
|
+
wrapper.vm.filters = [filter];
|
|
1325
|
+
wrapper.vm.updateFiltersFromProps([
|
|
1326
|
+
{
|
|
1327
|
+
key: 'filter0',
|
|
1328
|
+
label: 'new label',
|
|
1329
|
+
type: 'input',
|
|
1330
|
+
selectOptions: [{ label: 'option1', value: '1' }],
|
|
1331
|
+
},
|
|
1332
|
+
]);
|
|
1333
|
+
expect(wrapper.vm.filters).toStrictEqual([filter]);
|
|
1334
|
+
});
|
|
1335
|
+
test('should keep value if is in new options', () => {
|
|
1336
|
+
const wrapper = factory();
|
|
1337
|
+
const filter: Filter = {
|
|
1338
|
+
key: 'filter0',
|
|
1339
|
+
label: 'Zéro',
|
|
1340
|
+
type: 'select',
|
|
1341
|
+
selectOptions: [
|
|
1342
|
+
{ label: 'option1', value: '1' },
|
|
1343
|
+
{ label: 'option2', value: '2' },
|
|
1344
|
+
],
|
|
1345
|
+
};
|
|
1346
|
+
|
|
1347
|
+
wrapper.vm.filters = [filter];
|
|
1348
|
+
wrapper.vm.updateFiltersFromProps([
|
|
1349
|
+
{
|
|
1350
|
+
key: 'filter0',
|
|
1351
|
+
label: 'Zéro',
|
|
1352
|
+
type: 'select',
|
|
1353
|
+
selectOptions: [
|
|
1354
|
+
{ label: 'option1', value: '1' },
|
|
1355
|
+
{ label: 'option3', value: '3' },
|
|
1356
|
+
],
|
|
1357
|
+
},
|
|
1358
|
+
]);
|
|
1359
|
+
expect(wrapper.vm.filters).toStrictEqual([
|
|
1360
|
+
{
|
|
1361
|
+
...filter,
|
|
1362
|
+
selectOptions: [
|
|
1363
|
+
{ label: 'option1', value: '1' },
|
|
1364
|
+
{ label: 'option3', value: '3' },
|
|
1365
|
+
],
|
|
1366
|
+
},
|
|
1367
|
+
]);
|
|
1368
|
+
});
|
|
1369
|
+
});
|
|
1295
1370
|
});
|
|
1296
1371
|
});
|
|
@@ -183,6 +183,7 @@ export const useSearch = (
|
|
|
183
183
|
reflectSearchToUserPref(search.value);
|
|
184
184
|
}
|
|
185
185
|
});
|
|
186
|
+
|
|
186
187
|
watch(
|
|
187
188
|
() => filters,
|
|
188
189
|
() => {
|
|
@@ -233,19 +234,23 @@ export const useSearch = (
|
|
|
233
234
|
});
|
|
234
235
|
};
|
|
235
236
|
|
|
237
|
+
const resetFilterValue = (filter: Filter) => {
|
|
238
|
+
let resetFilter = { ...filter };
|
|
239
|
+
const valueKeys = ['value', 'valueFrom', 'valueTo'];
|
|
240
|
+
valueKeys.forEach((key) => {
|
|
241
|
+
if (
|
|
242
|
+
resetFilter[key as keyof Filter] !== null &&
|
|
243
|
+
resetFilter[key as keyof Filter] !== undefined
|
|
244
|
+
) {
|
|
245
|
+
resetFilter[key as keyof Filter] = null;
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
return resetFilter;
|
|
249
|
+
};
|
|
250
|
+
|
|
236
251
|
const resetFilters = () => {
|
|
237
252
|
filters.value = filters.value.map((filter) => {
|
|
238
|
-
|
|
239
|
-
const valueKeys = ['value', 'valueFrom', 'valueTo'];
|
|
240
|
-
valueKeys.forEach((key) => {
|
|
241
|
-
if (
|
|
242
|
-
resetFilter[key as keyof Filter] !== null &&
|
|
243
|
-
resetFilter[key as keyof Filter] !== undefined
|
|
244
|
-
) {
|
|
245
|
-
resetFilter[key as keyof Filter] = null;
|
|
246
|
-
}
|
|
247
|
-
});
|
|
248
|
-
return resetFilter;
|
|
253
|
+
return resetFilterValue(filter);
|
|
249
254
|
});
|
|
250
255
|
};
|
|
251
256
|
|
|
@@ -264,6 +269,43 @@ export const useSearch = (
|
|
|
264
269
|
}
|
|
265
270
|
};
|
|
266
271
|
|
|
272
|
+
const updateFiltersFromProps = (updatedFilters: Filter[]) => {
|
|
273
|
+
filters.value = filters.value.map((filter) => {
|
|
274
|
+
const updatedFilter = updatedFilters.find((f) => f.key === filter.key);
|
|
275
|
+
|
|
276
|
+
if (updatedFilter) {
|
|
277
|
+
let mergedFilter = { ...filter };
|
|
278
|
+
|
|
279
|
+
if (updatedFilter.autocompleteOptions)
|
|
280
|
+
mergedFilter.autocompleteOptions = updatedFilter.autocompleteOptions;
|
|
281
|
+
if (updatedFilter.selectOptions)
|
|
282
|
+
mergedFilter.selectOptions = updatedFilter.selectOptions;
|
|
283
|
+
|
|
284
|
+
const value = filter.value || filter.valueFrom || filter.valueTo;
|
|
285
|
+
|
|
286
|
+
const isValueValidSelectOption =
|
|
287
|
+
updatedFilter.type === 'select' &&
|
|
288
|
+
updatedFilter.selectOptions?.find((option) => option.value === value);
|
|
289
|
+
|
|
290
|
+
const isValueValidAutocompleteOption =
|
|
291
|
+
updatedFilter.type === 'autocomplete' &&
|
|
292
|
+
updatedFilter.autocompleteOptions?.find((option) => option === value);
|
|
293
|
+
|
|
294
|
+
if (
|
|
295
|
+
value &&
|
|
296
|
+
!isValueValidSelectOption &&
|
|
297
|
+
!isValueValidAutocompleteOption
|
|
298
|
+
) {
|
|
299
|
+
mergedFilter = resetFilterValue(mergedFilter);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
return mergedFilter;
|
|
303
|
+
} else {
|
|
304
|
+
return filter;
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
};
|
|
308
|
+
|
|
267
309
|
return {
|
|
268
310
|
search,
|
|
269
311
|
reflect,
|
|
@@ -277,6 +319,7 @@ export const useSearch = (
|
|
|
277
319
|
resetFilters,
|
|
278
320
|
selectSavedFilter,
|
|
279
321
|
resetAllFilters,
|
|
322
|
+
updateFiltersFromProps,
|
|
280
323
|
};
|
|
281
324
|
};
|
|
282
325
|
|
|
@@ -24,17 +24,17 @@
|
|
|
24
24
|
</span>
|
|
25
25
|
</div>
|
|
26
26
|
|
|
27
|
-
<div v-if="captions?.length" class="field__captions">
|
|
27
|
+
<div v-if="captions?.length || errors?.length" class="field__captions">
|
|
28
28
|
<div
|
|
29
|
+
v-if="captions?.length"
|
|
29
30
|
v-for="caption in captions"
|
|
30
31
|
:key="getCaptionIdentifier(caption)"
|
|
31
32
|
class="information field__caption"
|
|
32
33
|
>
|
|
33
34
|
<BmsCaption :caption="caption" />
|
|
34
35
|
</div>
|
|
35
|
-
</div>
|
|
36
|
-
<div v-if="errors?.length" class="field__errors">
|
|
37
36
|
<div
|
|
37
|
+
v-if="errors?.length"
|
|
38
38
|
v-for="error in computedErrors"
|
|
39
39
|
:key="error.label"
|
|
40
40
|
class="field__error"
|
|
@@ -186,7 +186,9 @@ const getCaptionIdentifier = (caption: string | Caption): string => {
|
|
|
186
186
|
--field-padding: 0.5em;
|
|
187
187
|
--field-margin: 0;
|
|
188
188
|
--field-label-font-weight: normal;
|
|
189
|
-
|
|
189
|
+
.field__captions {
|
|
190
|
+
margin-top: 0.5rem;
|
|
191
|
+
}
|
|
190
192
|
}
|
|
191
193
|
|
|
192
194
|
&.is-error {
|
|
@@ -27,15 +27,6 @@ Default.args = {
|
|
|
27
27
|
})),
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
-
export const WithSelectedItem = Template.bind({});
|
|
31
|
-
WithSelectedItem.args = {
|
|
32
|
-
currentSelectedItemIndex: 1,
|
|
33
|
-
options: ['toto', 'titi', 'tutu', 'tirlitititututatoooo'].map((i) => ({
|
|
34
|
-
label: i,
|
|
35
|
-
value: i,
|
|
36
|
-
})),
|
|
37
|
-
};
|
|
38
|
-
|
|
39
30
|
export const CanAddNewOption = Template.bind({});
|
|
40
31
|
CanAddNewOption.args = {
|
|
41
32
|
options: ['toto', 'titi', 'tutu', 'tirlitititututatoooo'].map((i) => ({
|
|
@@ -1,29 +1,21 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<ul
|
|
3
|
-
class="options-list"
|
|
4
|
-
data-testid="select-options"
|
|
5
|
-
@keydown.up="keyUp"
|
|
6
|
-
@keydown.down="keyDown"
|
|
7
|
-
@keydown.enter="keyEnter"
|
|
8
|
-
>
|
|
2
|
+
<ul class="options-list" data-testid="select-options">
|
|
9
3
|
<li
|
|
10
4
|
v-for="(option, index) in options"
|
|
11
5
|
:key="index"
|
|
12
6
|
:data-testid="option.value"
|
|
13
7
|
:class="{
|
|
8
|
+
'datalist-option': true,
|
|
14
9
|
selected: index === currentSelectedItemIndex,
|
|
15
10
|
small,
|
|
16
11
|
}"
|
|
17
|
-
@click.
|
|
12
|
+
@click.stop="onClick(option)"
|
|
18
13
|
>
|
|
19
14
|
<slot name="option" :option="option">
|
|
20
15
|
{{ option.label === null ? 'N/A' : option.label }}
|
|
21
16
|
</slot>
|
|
22
17
|
</li>
|
|
23
|
-
<li
|
|
24
|
-
v-if="displayNewOption"
|
|
25
|
-
@click.prevent="$emits('addNewOption', newOption)"
|
|
26
|
-
>
|
|
18
|
+
<li v-if="displayNewOption" @click.stop="$emits('addNewOption', newOption)">
|
|
27
19
|
<slot name="new-option"> {{ newOption }} (nouvelle option) </slot>
|
|
28
20
|
</li>
|
|
29
21
|
</ul>
|
|
@@ -31,7 +23,7 @@
|
|
|
31
23
|
|
|
32
24
|
<script setup lang="ts">
|
|
33
25
|
import { InputOption } from '@/models';
|
|
34
|
-
import { computed, onMounted, ref } from 'vue';
|
|
26
|
+
import { computed, onMounted, onUnmounted, ref } from 'vue';
|
|
35
27
|
|
|
36
28
|
export interface Props {
|
|
37
29
|
options: InputOption[];
|
|
@@ -52,17 +44,24 @@ const currentSelectedItemIndex = ref<number>(-1);
|
|
|
52
44
|
const $emits = defineEmits<{
|
|
53
45
|
select: [option: any];
|
|
54
46
|
addNewOption: [option: string];
|
|
47
|
+
blur: [];
|
|
55
48
|
}>();
|
|
56
49
|
|
|
57
50
|
const keyDownEventListener = (ev: KeyboardEvent) => {
|
|
58
51
|
if (props.isInputFocused) {
|
|
59
52
|
switch (ev.key) {
|
|
60
53
|
case 'ArrowDown':
|
|
54
|
+
ev.preventDefault();
|
|
61
55
|
return keyDown();
|
|
62
56
|
case 'ArrowUp':
|
|
57
|
+
ev.preventDefault();
|
|
63
58
|
return keyUp();
|
|
64
59
|
case 'Enter':
|
|
60
|
+
ev.preventDefault();
|
|
65
61
|
return keyEnter();
|
|
62
|
+
case 'Escape':
|
|
63
|
+
ev.preventDefault();
|
|
64
|
+
return keyEscape();
|
|
66
65
|
default:
|
|
67
66
|
return;
|
|
68
67
|
}
|
|
@@ -96,6 +95,10 @@ const keyEnter = () => {
|
|
|
96
95
|
}
|
|
97
96
|
};
|
|
98
97
|
|
|
98
|
+
const keyEscape = () => {
|
|
99
|
+
$emits('blur');
|
|
100
|
+
};
|
|
101
|
+
|
|
99
102
|
const onClick = (option: { label: string; value: any }) => {
|
|
100
103
|
$emits('select', option);
|
|
101
104
|
};
|
|
@@ -5,8 +5,8 @@ export interface FieldComponentProps {
|
|
|
5
5
|
required?: boolean;
|
|
6
6
|
optional?: boolean;
|
|
7
7
|
helperText?: string;
|
|
8
|
-
errors?: string
|
|
9
|
-
captions?: string
|
|
8
|
+
errors?: (string | Caption)[];
|
|
9
|
+
captions?: (string | Caption)[];
|
|
10
10
|
disabled?: boolean;
|
|
11
11
|
small?: boolean;
|
|
12
12
|
}
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
:can-add-new-option="true"
|
|
12
12
|
@add-new-option="onAddNewOption"
|
|
13
13
|
/>
|
|
14
|
-
|
|
15
14
|
Valeur: {{ inputValueIcon }}
|
|
16
15
|
<BmsAutocomplete
|
|
17
16
|
label="Autocomplete avec icones"
|
|
@@ -26,6 +25,20 @@
|
|
|
26
25
|
:options="optionsText"
|
|
27
26
|
v-model="inputText"
|
|
28
27
|
/>
|
|
28
|
+
|
|
29
|
+
<BmsSelect
|
|
30
|
+
label="Select"
|
|
31
|
+
@blur="console.log('blur')"
|
|
32
|
+
v-model="select"
|
|
33
|
+
:options="optionsLabelValue"
|
|
34
|
+
/>
|
|
35
|
+
|
|
36
|
+
<BmsMultiSelect
|
|
37
|
+
label="Multi-select"
|
|
38
|
+
v-model="multiSelect"
|
|
39
|
+
:options="optionsLabelValue"
|
|
40
|
+
/>
|
|
41
|
+
<br />
|
|
29
42
|
</template>
|
|
30
43
|
|
|
31
44
|
<script setup lang="ts">
|
|
@@ -34,6 +47,14 @@ import { Heart, Cat } from 'lucide-vue-next';
|
|
|
34
47
|
import { range } from 'lodash';
|
|
35
48
|
import { ref } from 'vue';
|
|
36
49
|
import BmsButton from '@/components/button/BmsButton.vue';
|
|
50
|
+
import BmsSelect from '@/components/form/BmsSelect.vue';
|
|
51
|
+
import BmsMultiSelect from '@/components/form/BmsMultiSelect.vue';
|
|
52
|
+
import FieldDatalist from '@/plugins/field/FieldDatalist.vue';
|
|
53
|
+
import RawAutocomplete from '@/components/form/RawAutocomplete.vue';
|
|
54
|
+
import BmsInputText from '@/components/form/BmsInputText.vue';
|
|
55
|
+
|
|
56
|
+
const select = ref('');
|
|
57
|
+
const multiSelect = ref([]);
|
|
37
58
|
|
|
38
59
|
const optionsLabelValue = ref(
|
|
39
60
|
range(0, 30).map((i) =>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
+
{{ filters }}
|
|
2
3
|
<bms-server-table
|
|
3
4
|
v-model:selectedItems="selectedItems"
|
|
4
5
|
v-model:selectMode="selectMode"
|
|
@@ -13,6 +14,8 @@
|
|
|
13
14
|
:total="totalItems"
|
|
14
15
|
@saveFilter="onSaveFilter"
|
|
15
16
|
@deleteSavedFilter="onDeleteSavedFilter"
|
|
17
|
+
@filterInput="onFilterInput"
|
|
18
|
+
@filterChange="onFilterChange"
|
|
16
19
|
>
|
|
17
20
|
<template #default="{ row }: { row: any }">
|
|
18
21
|
<td>
|
|
@@ -40,7 +43,7 @@
|
|
|
40
43
|
<script lang="ts" setup>
|
|
41
44
|
import { Filter, SavedFilter, SelectMode } from '@/models';
|
|
42
45
|
import axios from 'axios';
|
|
43
|
-
import { Ref, ref } from 'vue';
|
|
46
|
+
import { computed, Ref, ref } from 'vue';
|
|
44
47
|
import { isEmptyStringOrNotDefined } from '@/helpers';
|
|
45
48
|
|
|
46
49
|
const serverHeaders = [
|
|
@@ -49,7 +52,27 @@ const serverHeaders = [
|
|
|
49
52
|
{ label: 'Type', key: 'type' },
|
|
50
53
|
];
|
|
51
54
|
|
|
52
|
-
const
|
|
55
|
+
const typeOptions = ref([
|
|
56
|
+
'Grass',
|
|
57
|
+
'Poison',
|
|
58
|
+
'Fire',
|
|
59
|
+
'Flying',
|
|
60
|
+
'Water',
|
|
61
|
+
'Bug',
|
|
62
|
+
'Normal',
|
|
63
|
+
'Electric',
|
|
64
|
+
'Ground',
|
|
65
|
+
'Fairy',
|
|
66
|
+
'Fighting',
|
|
67
|
+
'Psychic',
|
|
68
|
+
'Rock',
|
|
69
|
+
'Steel',
|
|
70
|
+
'Ice',
|
|
71
|
+
'Ghost',
|
|
72
|
+
'Dragon',
|
|
73
|
+
]);
|
|
74
|
+
|
|
75
|
+
const filters = computed(() => [
|
|
53
76
|
{
|
|
54
77
|
label: 'Name',
|
|
55
78
|
key: 'name',
|
|
@@ -65,27 +88,9 @@ const filters = [
|
|
|
65
88
|
label: 'Type',
|
|
66
89
|
key: 'type',
|
|
67
90
|
type: 'autocomplete',
|
|
68
|
-
autocompleteOptions:
|
|
69
|
-
'Grass',
|
|
70
|
-
'Poison',
|
|
71
|
-
'Fire',
|
|
72
|
-
'Flying',
|
|
73
|
-
'Water',
|
|
74
|
-
'Bug',
|
|
75
|
-
'Normal',
|
|
76
|
-
'Electric',
|
|
77
|
-
'Ground',
|
|
78
|
-
'Fairy',
|
|
79
|
-
'Fighting',
|
|
80
|
-
'Psychic',
|
|
81
|
-
'Rock',
|
|
82
|
-
'Steel',
|
|
83
|
-
'Ice',
|
|
84
|
-
'Ghost',
|
|
85
|
-
'Dragon',
|
|
86
|
-
],
|
|
91
|
+
autocompleteOptions: typeOptions.value,
|
|
87
92
|
},
|
|
88
|
-
];
|
|
93
|
+
]);
|
|
89
94
|
|
|
90
95
|
const savedFilters: Ref<SavedFilter[]> = ref<SavedFilter[]>([]);
|
|
91
96
|
const selectedItems = ref<any[]>([]);
|
|
@@ -102,6 +107,32 @@ const onDeleteSavedFilter = (savedFilter: SavedFilter) => {
|
|
|
102
107
|
);
|
|
103
108
|
};
|
|
104
109
|
|
|
110
|
+
const onFilterInput = ({
|
|
111
|
+
filterKey,
|
|
112
|
+
e,
|
|
113
|
+
}: {
|
|
114
|
+
filterKey: string;
|
|
115
|
+
e: InputEvent;
|
|
116
|
+
}) => {
|
|
117
|
+
typeOptions.value = [];
|
|
118
|
+
console.log(
|
|
119
|
+
`user filtered key ${filterKey} with val ${(e.target as HTMLInputElement)?.value}`,
|
|
120
|
+
);
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
const onFilterChange = ({
|
|
124
|
+
filterKey,
|
|
125
|
+
e,
|
|
126
|
+
}: {
|
|
127
|
+
filterKey: string;
|
|
128
|
+
e: InputEvent;
|
|
129
|
+
}) => {
|
|
130
|
+
typeOptions.value = [];
|
|
131
|
+
console.log(
|
|
132
|
+
`user filtered key ${filterKey} changed with val ${(e.target as HTMLInputElement)?.value}`,
|
|
133
|
+
);
|
|
134
|
+
};
|
|
135
|
+
|
|
105
136
|
const customFetchData = async (
|
|
106
137
|
params: any,
|
|
107
138
|
abortController: AbortController,
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<BmsBackButton :fallback="{ path: '/' }" />
|
|
3
|
+
<br />
|
|
4
|
+
<BmsButton @click="changeChoice">Change choice</BmsButton>
|
|
3
5
|
<bms-table
|
|
4
6
|
:headers="headers"
|
|
5
7
|
:filters="filters"
|
|
@@ -13,6 +15,8 @@
|
|
|
13
15
|
v-model:selectedItems="selectedItems"
|
|
14
16
|
@saveFilter="onSaveFilter"
|
|
15
17
|
@deleteSavedFilter="onDeleteSavedFilter"
|
|
18
|
+
@filterInput="onFilterInput"
|
|
19
|
+
@filterChange="onFilterChange"
|
|
16
20
|
>
|
|
17
21
|
<template #choice2="{ row }">
|
|
18
22
|
<BmsTooltip tooltipText="tooltip">
|
|
@@ -140,7 +144,6 @@ const items = Array(100)
|
|
|
140
144
|
|
|
141
145
|
const savedFilters: Ref<SavedFilter[]> = ref<SavedFilter[]>([]);
|
|
142
146
|
const selectedItems: Ref<any[]> = ref([]);
|
|
143
|
-
|
|
144
147
|
const onSaveFilter = (savedFilter: SavedFilter) => {
|
|
145
148
|
savedFilters.value.push(savedFilter);
|
|
146
149
|
};
|
|
@@ -151,7 +154,28 @@ const onDeleteSavedFilter = (savedFilter: SavedFilter) => {
|
|
|
151
154
|
);
|
|
152
155
|
};
|
|
153
156
|
|
|
154
|
-
const
|
|
157
|
+
const onFilterInput = ({
|
|
158
|
+
filterKey,
|
|
159
|
+
e,
|
|
160
|
+
value,
|
|
161
|
+
}: {
|
|
162
|
+
filterKey: string;
|
|
163
|
+
e: InputEvent;
|
|
164
|
+
value: any;
|
|
165
|
+
}) => {
|
|
166
|
+
console.log(`Input in filter ${filterKey} with val ${value}`);
|
|
167
|
+
};
|
|
168
|
+
const onFilterChange = ({
|
|
169
|
+
filterKey,
|
|
170
|
+
value,
|
|
171
|
+
}: {
|
|
172
|
+
filterKey: string;
|
|
173
|
+
value: any;
|
|
174
|
+
}) => {
|
|
175
|
+
console.log(`Change in filter ${filterKey} with val`, value);
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
const filters = ref<Filter[]>([
|
|
155
179
|
{
|
|
156
180
|
label: 'inputText Colonne 1',
|
|
157
181
|
key: 'column1',
|
|
@@ -199,5 +223,20 @@ const filters: Filter[] = [
|
|
|
199
223
|
customFilter: (item: any, value: any, target: string) =>
|
|
200
224
|
item[target] > 0.5 === value,
|
|
201
225
|
},
|
|
202
|
-
];
|
|
226
|
+
]);
|
|
227
|
+
const changeChoice = () => {
|
|
228
|
+
filters.value = filters.value.map((f) =>
|
|
229
|
+
f.key === 'choice2'
|
|
230
|
+
? {
|
|
231
|
+
...f,
|
|
232
|
+
selectOptions: [
|
|
233
|
+
{ label: 'huey', value: 'huey' },
|
|
234
|
+
{ label: 'riri', value: 'riri' },
|
|
235
|
+
{ label: 'fifi', value: 'fifi' },
|
|
236
|
+
{ label: 'loulou', value: 'loulou' },
|
|
237
|
+
],
|
|
238
|
+
}
|
|
239
|
+
: f,
|
|
240
|
+
);
|
|
241
|
+
};
|
|
203
242
|
</script>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import FieldDatalist, { type Props } from '@/plugins/field/FieldDatalist.vue';
|
|
2
|
-
import { mount } from '@vue/test-utils';
|
|
3
|
-
import { field } from '@/plugins/field';
|
|
4
|
-
|
|
5
|
-
const factory = (props?: Props) => {
|
|
6
|
-
const wrapper = mount(FieldDatalist, {
|
|
7
|
-
global: {
|
|
8
|
-
plugins: [field],
|
|
9
|
-
},
|
|
10
|
-
props: {
|
|
11
|
-
isInputFocused: false,
|
|
12
|
-
options: [
|
|
13
|
-
{ label: 'titi', value: 'i' },
|
|
14
|
-
{ label: 'toto', value: 'o' },
|
|
15
|
-
{ label: 'tutu', value: 'u' },
|
|
16
|
-
],
|
|
17
|
-
modelValue: '',
|
|
18
|
-
...props,
|
|
19
|
-
},
|
|
20
|
-
attachTo: document.body,
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
return { wrapper };
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
describe('FieldDatalist', () => {
|
|
27
|
-
it('should be able to select with keyboard', async () => {
|
|
28
|
-
const { wrapper } = factory();
|
|
29
|
-
const titi = wrapper.get('[data-testid="i"]');
|
|
30
|
-
|
|
31
|
-
expect(titi.classes()).toStrictEqual([]);
|
|
32
|
-
await wrapper.trigger('keydown.down');
|
|
33
|
-
expect(titi.classes()).toStrictEqual(['selected']);
|
|
34
|
-
});
|
|
35
|
-
});
|