Commit 1be217e5 authored by MARCO Jonathan's avatar MARCO Jonathan
Browse files

馃悰 Fix the option search bug

Fix VUE-FORMBUILDER-FY VUE-FORMBUILDER-G0 VUE-FORMBUILDER-FZ VUE-FORMBUILDER-FX VUE-FORMBUILDER-FW VUE-FORMBUILDER-G3 VUE-FORMBUILDER-G5 VUE-FORMBUILDER-G4 VUE-FORMBUILDER-G2 VUE-FORMBUILDER-G1
parent d0f53f74
......@@ -2,47 +2,47 @@
<v-row class="flex-column">
<v-col v-if="isSelectable">
<v-switch
hide-details
:label="_uct('builder.tabs.data.multiple')"
:input-value="field.multiple"
@change="updateField('multiple', $event)"
hide-details
:label="_uct('builder.tabs.data.multiple')"
:input-value="field.multiple"
@change="updateField('multiple', $event)"
/>
</v-col>
<v-card v-if="hasOptions" flat>
<v-card-title>
{{ _uct('builder.tabs.data.options.title') }}
<v-spacer />
<v-spacer/>
<v-select
dense
hide-details
clearable
class="mr-1"
:items="dependsOnItems"
item-text="name"
item-value="id"
:label="_uct('builder.tabs.data.options.dependsOn')"
:value="field.dependsOn"
@change="updateField('dependsOn', $event)"
dense
hide-details
clearable
class="mr-1"
:items="dependsOnItems"
item-text="name"
item-value="id"
:label="_uct('builder.tabs.data.options.dependsOn')"
:value="field.dependsOn"
@change="updateField('dependsOn', $event)"
/>
<v-text-field
v-model="searchOption"
dense
hide-details
class="mx-1"
:label="_uct('builder.tabs.data.options.search')"
append-icon="mdi-magnify"
v-model="searchOption"
dense
hide-details
class="mx-1"
:label="_uct('builder.tabs.data.options.search')"
append-icon="mdi-magnify"
/>
<!-- New option Dialog -->
<v-dialog v-model="newOptionDialog" max-width="400">
<template v-slot:activator="{ on }">
<v-btn
v-on="on"
class="mx-1"
color="primary"
:class="{ 'light-button': !primaryIsDark }"
fab
x-small
v-on="on"
class="mx-1"
color="primary"
:class="{ 'light-button': !primaryIsDark }"
fab
x-small
>
<v-icon>mdi-plus</v-icon>
</v-btn>
......@@ -56,14 +56,14 @@
<v-row>
<v-col>
<v-text-field
v-model="newOption.label"
:label="_uct('builder.tabs.data.dialogNewOption.label')"
v-model="newOption.label"
:label="_uct('builder.tabs.data.dialogNewOption.label')"
/>
</v-col>
<v-col>
<v-text-field
v-model="newOption.value"
:label="_uct('builder.tabs.data.dialogNewOption.value')"
v-model="newOption.value"
:label="_uct('builder.tabs.data.dialogNewOption.value')"
/>
</v-col>
</v-row>
......@@ -71,7 +71,7 @@
</v-card-text>
<v-card-actions>
<v-spacer />
<v-spacer/>
<v-btn tile elevation="0" color="primary" outlined @click="closeNewOptionDialog">
{{ _uct('builder.tabs.data.dialogNewOption.actions.cancel') }}
</v-btn>
......@@ -84,34 +84,34 @@
<v-btn
color="primary"
:class="{ 'light-button': !primaryIsDark }"
class="ml-1"
fab x-small
@click="sortOptions"
color="primary"
:class="{ 'light-button': !primaryIsDark }"
class="ml-1"
fab x-small
@click="sortOptions"
>
<v-icon>mdi-sort-alphabetical-descending</v-icon>
</v-btn>
<usf-tab-data-input-select-import-options :field="field" />
<usf-tab-data-input-select-import-options :field="field"/>
</v-card-title>
<!-- Data table with the option list -->
<v-data-table
dense
:headers="optionsTableHeaders"
:items="fieldOptions"
:search="searchOption"
:custom-filter="customFilter"
dense
:headers="optionsTableHeaders"
:items="fieldOptions"
:search="searchOption"
:custom-filter="customFilter"
>
<template v-slot:item.label="{ item }">
<v-edit-dialog :return-value="item.label">
{{ item.label }}
<template v-slot:input>
<v-text-field
:label="_uct('builder.tabs.data.dataTable.headers.label')"
:value="item.label"
@change="updateOption(item.id, 'label', $event)"
:label="_uct('builder.tabs.data.dataTable.headers.label')"
:value="item.label"
@change="updateOption(item.id, 'label', $event)"
/>
</template>
</v-edit-dialog>
......@@ -121,9 +121,9 @@
{{ item.value }}
<template v-slot:input>
<v-text-field
:label="_uct('builder.tabs.data.dataTable.headers.value')"
:value="item.value"
@change="updateOption(item.id, 'value', $event)"
:label="_uct('builder.tabs.data.dataTable.headers.value')"
:value="item.value"
@change="updateOption(item.id, 'value', $event)"
/>
</template>
</v-edit-dialog>
......@@ -139,37 +139,37 @@
<span v-else>{{ _uct('builder.tabs.data.dataTable.displayBy.noDisplayed') }}</span>
<template v-slot:input>
<v-combobox
v-if="field.dependsOn.startsWith('user')"
:label="_uct('builder.tabs.data.dataTable.headers.userAttributeValue')"
chips
deletable-chips
multiple
clearable
:value="item.displayedBy"
@change="updateOption(item.id, 'displayedBy', $event)"
v-if="field.dependsOn.startsWith('user')"
:label="_uct('builder.tabs.data.dataTable.headers.userAttributeValue')"
chips
deletable-chips
multiple
clearable
:value="item.displayedBy"
@change="updateOption(item.id, 'displayedBy', $event)"
/>
<usf-tab-data-input-displayed-by-select
v-else
:selected="item.displayedBy"
:owner="field.dependsOn"
@new-selection="updateOption(item.id, 'displayedBy', $event)"
v-else
:selected="item.displayedBy"
:owner="field.dependsOn"
@new-selection="updateOption(item.id, 'displayedBy', $event)"
/>
</template>
</v-edit-dialog>
</template>
<template v-slot:item.actions="{ item }">
<v-icon
v-if="field.options.indexOf(item.id) < field.options.length - 1"
small
@click="optionAction(item.id, 1)"
v-if="field.options.indexOf(item.id) < field.options.length - 1"
small
@click="optionAction(item.id, 1)"
>
mdi-arrow-down-bold
</v-icon>
<v-icon
v-if="field.options.indexOf(item.id) > 0"
class="mx-1"
small
@click="optionAction(item.id, -1)"
v-if="field.options.indexOf(item.id) > 0"
class="mx-1"
small
@click="optionAction(item.id, -1)"
>
mdi-arrow-up-bold
</v-icon>
......@@ -177,8 +177,8 @@
</template>
<template v-slot:item.defaultValue="{ item }">
<v-checkbox
:input-value="item.id === defaultOption"
@change="onUpdateDefaultOption($event, item)"
:input-value="item.id === defaultOption"
@change="onUpdateDefaultOption($event, item)"
/>
</template>
</v-data-table>
......@@ -187,14 +187,14 @@
</template>
<script lang="ts">
import { UsfTabDataInputDisplayedBySelect } from '../UsfTabDataInputDisplayedBySelect';
import { mapActions } from 'vuex';
import {UsfTabDataInputDisplayedBySelect} from '../UsfTabDataInputDisplayedBySelect';
import {mapActions} from 'vuex';
import Vue from 'vue';
import { Field, Option } from '#form-plugin/models/form';
import {Field, Option} from '#form-plugin/models/form';
import UsfTabDataInputSelectImportOptions
from '../UsfTabDataInputSelectImportOptions/UsfTabDataInputSelectImportOptions.vue';
import { Control } from '#form-plugin/models/control';
import { DataTableHeader } from 'vuetify';
import {Control} from '#form-plugin/models/control';
import {DataTableHeader} from 'vuetify';
export default Vue.extend({
name: 'UsfTabDataInput',
......@@ -243,30 +243,30 @@ export default Vue.extend({
},
userTemplatesAttributes() {
return this.$store.getters['user/templatesNames']
.map(template => {
return [
{
header: `${template.charAt(0)
.toUpperCase()}${template.slice(1)}`,
},
...this.$store.getters['user/templateAttributes'](template),
];
})
.reduce((acc, current) => acc.concat(current), [])
.concat([{ divider: true }]);
.map(template => {
return [
{
header: `${template.charAt(0)
.toUpperCase()}${template.slice(1)}`,
},
...this.$store.getters['user/templateAttributes'](template),
];
})
.reduce((acc, current) => acc.concat(current), [])
.concat([{divider: true}]);
},
otherSelectableInputs() {
const fieldsArray: Field[] = this.$store.getters['form/getFieldsArray'];
const otherSelectableInputs = fieldsArray
? fieldsArray
.filter((input) => {
const inputSubtypes = this.$store.getters['formBuilder/controls/getControlById'](input.component).usfSubtypes;
return inputSubtypes.some(subtype => subtype === 'withOptions') && input.id !== this.field.id;
})
.map(({ id, name }) => ({ id, name: name || id }))
: [];
? fieldsArray
.filter((input) => {
const inputSubtypes = this.$store.getters['formBuilder/controls/getControlById'](input.component).usfSubtypes;
return inputSubtypes.some(subtype => subtype === 'withOptions') && input.id !== this.field.id;
})
.map(({id, name}) => ({id, name: name || id}))
: [];
return [{ header: 'Selectable inputs' }, ...otherSelectableInputs];
return [{header: 'Selectable inputs'}, ...otherSelectableInputs];
},
dependsOnItems() {
return [
......@@ -275,7 +275,9 @@ export default Vue.extend({
];
},
fieldOptions() {
return this.field.options.map(optionId => this.$store.getters['form/getOptionByIdOrValue'](optionId));
return this.field.options.map(optionId => {
return this.$store.getters['form/getOptionByIdOrValue'](optionId);
});
},
optionsTableHeaders(): DataTableHeader[] {
const optionsTableHeaders: DataTableHeader[] = [
......@@ -331,26 +333,34 @@ export default Vue.extend({
this.newOption = Object.assign({}, this.newOptionDefault);
}, 300);
},
customFilter(itemLabel: string, search: string | null, item: Option): boolean {
customFilter(itemLabel: string | string[], search: string | null, item: Option): boolean {
if (search === null) return true;
/**
* Quand un 茅l茅ment est cach茅 par une recherche (car il ne correspond par 脿 "search",
* le v-data-table relance une seconde fois la recherche avec en label le displayedBy
* pour 茅viter de faire crasher la recherche si c'est la "seconde recherche" il retourne false
*/
if (typeof itemLabel !== 'string') return false
const searchLower = search.toLocaleLowerCase();
if (!!item.displayedBy?.length) {
return itemLabel?.toLowerCase().includes(search) || item.displayedBy.some((optionId) => {
return itemLabel?.toLowerCase().includes(searchLower) || item.displayedBy.some((optionId) => {
const option: Option | undefined = this.getOption(optionId);
if (option) {
return optionId.toLowerCase().includes(search) || option.label.toLowerCase().includes(search);
return optionId.toLowerCase().includes(searchLower) || option.label.toLowerCase().includes(searchLower);
}
return false;
});
}
return itemLabel.toLowerCase().includes(search)
return typeof itemLabel === 'string' && itemLabel && itemLabel?.toLowerCase().includes(search);
},
getOption(id): Option {
return this.$store.getters['form/getOptionByIdOrValue'](id);
},
getLabelOption(id): undefined | string {
return this.getOption(id)?.label
return this.getOption(id)?.label;
},
onUpdateDefaultOption(newValue, item) {
this.updateDefaultOption({
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment