diff --git a/src/components/Feature/Edit/FeatureExtraForm.vue b/src/components/Feature/Edit/FeatureExtraForm.vue index 3ae38ec519c52e664918ec5c33b58702c39cb126..e0e63f4c2059e5b68c4860769f5dd0e1c2d7899b 100644 --- a/src/components/Feature/Edit/FeatureExtraForm.vue +++ b/src/components/Feature/Edit/FeatureExtraForm.vue @@ -50,6 +50,67 @@ </li> </ul> </div> + + <div + v-else-if="field && field.field_type === 'pre_recorded_list'" + > + <label + v-if="displayLabels" + :for="field.name" + :class="{ required: field.is_mandatory }" + > + {{ field.label }} + </label> + <Multiselect + v-model="selectedPrerecordedValue" + :options="selectedPrerecordedListValues" + :options-limit="10" + :allow-empty="!field.is_mandatory" + track-by="label" + label="label" + :reset-after="false" + select-label="" + selected-label="" + deselect-label="" + :searchable="true" + :placeholder="'Recherchez une valeur de la liste pré-définie ...'" + :show-no-results="true" + :loading="loadingPrerecordedListValues" + :clear-on-select="false" + :preserve-search="false" + @search-change="search" + @select="selectPrerecordedValue" + > + <template slot="clear"> + <div + v-if="selectedPrerecordedValue" + class="multiselect__clear" + @click.prevent.stop="clear" + > + <i + class="close icon" + aria-hidden="true" + /> + </div> + </template> + <span slot="noResult"> + Aucun résultat. + </span> + <span slot="noOptions"> + Saisissez les premiers caractères ... + </span> + </Multiselect> + <ul + v-if="field.is_mandatory && error" + :id="`errorlist-extra-form-${field.name}`" + class="errorlist" + > + <li> + {{ error }} + </li> + </ul> + </div> + <div v-else-if="field && field.field_type === 'integer'"> <label v-if="displayLabels" @@ -177,12 +238,16 @@ <script> import Dropdown from '@/components/Dropdown.vue'; +import Multiselect from 'vue-multiselect'; + +import { mapState, mapMutations, mapActions } from 'vuex'; export default { name: 'FeatureExtraForm', components: { Dropdown, + Multiselect }, props: { @@ -194,11 +259,18 @@ export default { data() { return { - error: null + error: null, + prerecordedListSearchQuery: null, + loadingPrerecordedListValues: false, + selectedPrerecordedValue: null }; }, computed: { + ...mapState('feature-type', [ + 'selectedPrerecordedListValues' + ]), + selected_extra_form_list: { get() { return this.field.value || ''; @@ -221,10 +293,41 @@ export default { if (newValue) { this.error = null; } + }, + prerecordedListSearchQuery(newValue) { + if (newValue) { + this.loadingPrerecordedListValues = true; + this.GET_SELECTED_PRERECORDED_LIST_VALUES({ + name: this.field.options[0], + pattern: newValue + }) + .then(() => { + this.loadingPrerecordedListValues = false; + }) + .catch(() => { + this.loadingPrerecordedListValues = false; + }); + } else { + this.SET_SELECTED_PRERECORDED_LIST_VALUES([]); + } + } + }, + + created() { + console.log(this.field.value); + if (this.field.value) { + this.selectedPrerecordedValue = { label: this.field.value }; } }, methods: { + ...mapMutations('feature-type', [ + 'SET_SELECTED_PRERECORDED_LIST_VALUES' + ]), + ...mapActions('feature-type', [ + 'GET_SELECTED_PRERECORDED_LIST_VALUES' + ]), + updateStore_extra_form(evt) { const newExtraForm = this.field; if (this.field.field_type === 'boolean') { @@ -244,6 +347,21 @@ export default { this.error = null; } return isValid; + }, + + search(text) { + this.prerecordedListSearchQuery = text; + }, + + selectPrerecordedValue(e) { + this.selectedPrerecordedValue = e.label; + this.prerecordedListSearchQuery = null; + this.updateStore_extra_form({ target: { value: this.selectedPrerecordedValue } }); + }, + + clear() { + this.selectedPrerecordedValue = null; + this.prerecordedListSearchQuery = null; } }, }; diff --git a/src/components/FeatureType/FeatureTypeCustomForm.vue b/src/components/FeatureType/FeatureTypeCustomForm.vue index e5c34933c32d995a50df009079226900119062b5..a8f26395f670aed01728655abca5058778d2a58b 100644 --- a/src/components/FeatureType/FeatureTypeCustomForm.vue +++ b/src/components/FeatureType/FeatureTypeCustomForm.vue @@ -167,13 +167,38 @@ </li> </ul> </div> + + <div + v-if="selectedFieldType === 'Liste de valeurs pré-enregistrées'" + class="field required" + > + <label>{{ + form.options.label + }}</label> + <Dropdown + :options="preRecordedLists" + :selected="arrayOption" + :selection.sync="arrayOption" + /> + <ul + id="errorlist" + class="errorlist" + > + <li + v-for="error in form.options.errors" + :key="error" + > + {{ error }} + </li> + </ul> + </div> </div> </div> </div> </template> <script> -import { mapState } from 'vuex'; +import { mapState, mapActions } from 'vuex'; import Dropdown from '@/components/Dropdown.vue'; @@ -202,6 +227,7 @@ export default { { name: 'Chaîne de caractères', value: 'char' }, { name: 'Date', value: 'date' }, { name: 'Liste de valeurs', value: 'list' }, + { name: 'Liste de valeurs pré-enregistrées', value: 'pre_recorded_list' }, { name: 'Nombre entier', value: 'integer' }, { name: 'Nombre décimal', value: 'decimal' }, { name: 'Texte multiligne', value: 'text' }, @@ -268,12 +294,14 @@ export default { value: [], }, }, + selectedPrerecordedList: null }; }, computed: { ...mapState('feature-type', [ - 'customForms' + 'customForms', + 'preRecordedLists' ]), selectedFieldType: { // getter @@ -288,6 +316,9 @@ export default { }, // setter set(newValue) { + if (newValue.value === 'pre_recorded_list') { + this.GET_PRERECORDED_LISTS(); + } this.form.field_type.value = newValue.value; this.form = { ...this.form }; // ! quick & dirty fix for getter not updating because of Vue caveat https://vuejs.org/v2/guide/reactivity.html#For-Objects // Vue.set(this.form.field_type, "value", newValue.value); // ? vue.set didn't work, maybe should flatten form ? @@ -314,6 +345,9 @@ export default { }, methods: { + ...mapActions('feature-type', [ + 'GET_PRERECORDED_LISTS' + ]), setIsFieldMandatory(e) { this.form.isFieldMandatory = e.target.checked; @@ -389,8 +423,13 @@ export default { }, checkListOptions() { - if (this.form.field_type.value !== 'list') return true; - return this.form.options.value.length >= 2 && !this.form.options.value.includes(''); + if (!['list', 'pre_recorded_list'].includes(this.form.field_type.value)) return true; + if (this.form.field_type.value === 'list') { + return this.form.options.value.length >= 2 && !this.form.options.value.includes(''); + } + if (this.form.field_type.value === 'pre_recorded_list') { + return this.form.options.value.length === 1; + } }, checkCustomForm() { diff --git a/src/services/featureType-api.js b/src/services/featureType-api.js index 1aff32caedb23ebb9806dcd954964304ce4a2049..651e59dedf4f477e26db088a41256bd79fc7a6c1 100644 --- a/src/services/featureType-api.js +++ b/src/services/featureType-api.js @@ -1,5 +1,5 @@ import axios from '@/axios-client.js'; -import store from '../store'; +import store from '@/store'; const baseUrl = store.state.configuration.VUE_APP_DJANGO_API_BASE; diff --git a/src/store/modules/feature-type.store.js b/src/store/modules/feature-type.store.js index 0fe6b25c8de60295e8d2ba2a166fdd592ceead4e..1b04fa29a8a0e80322642b7b73148c38be734ee0 100644 --- a/src/store/modules/feature-type.store.js +++ b/src/store/modules/feature-type.store.js @@ -30,6 +30,8 @@ const feature_type = { feature_types: [], fileToImport: null, importFeatureTypeData: [], + preRecordedLists: [], + selectedPrerecordedListValues: [] }, getters: { @@ -83,6 +85,12 @@ const feature_type = { SET_FILE_TO_IMPORT(state, payload) { state.fileToImport = payload; }, + SET_PRERECORDED_LISTS(state, payload) { + state.preRecordedLists = payload; + }, + SET_SELECTED_PRERECORDED_LIST_VALUES(state, payload) { + state.selectedPrerecordedListValues = payload.slice(0, 10).map(el => { return { label: el };}); + } }, actions: { @@ -100,6 +108,32 @@ const feature_type = { }); }, + async GET_PRERECORDED_LISTS({ commit }) { + try { + const response = await axios.get( + `${this.state.configuration.VUE_APP_DJANGO_API_BASE}prerecorded-list-values/` + ); + if (response.status === 200) { + commit('SET_PRERECORDED_LISTS', response.data.map(el => el.name)); + } + } catch (err) { + console.error(err); + } + }, + + async GET_SELECTED_PRERECORDED_LIST_VALUES({ commit }, { name, pattern }) { + try { + const response = await axios.get( + `${this.state.configuration.VUE_APP_DJANGO_API_BASE}prerecorded-list-values/${name}/?pattern=${pattern}` + ); + if (response.status === 200) { + commit('SET_SELECTED_PRERECORDED_LIST_VALUES', response.data); + } + } catch (err) { + console.error(err); + } + }, + async SEND_FEATURE_TYPE({ state, getters, rootState }, requestType) { const data = { title: state.form.title.value,