diff --git a/vue/Element/CreationForm.vue b/vue/Element/CreationForm.vue index 8fea396155ece4b9c5ab98d875be41af1859bbb3..c70b725f24851303f80f1fd0c9fa35f2cd1826d1 100644 --- a/vue/Element/CreationForm.vue +++ b/vue/Element/CreationForm.vue @@ -80,6 +80,7 @@ :corpus-id="corpusId" allow-empty auto-select + v-on:submit="createElement" /> </div> </div> diff --git a/vue/Element/DetailsPanel.vue b/vue/Element/DetailsPanel.vue index d35f9c27e9c6905faf79fd0b259629650b5d0d4f..e636c85074863b4985d976a41431ee803637fa4d 100644 --- a/vue/Element/DetailsPanel.vue +++ b/vue/Element/DetailsPanel.vue @@ -54,29 +54,33 @@ <DropdownContent title="Classifications" :disabled="(!canWriteElement(elementId) || !hasMlClasses) && !classifications.length"> <HelpModal class="is-pulled-right" title="Help for classifications" :data="CLASSIFICATIONS_HELP" /> - <div v-if="canWriteElement(elementId) && hasMlClasses" class="field has-addons"> - <p class="control"> - <MLClassSelect - ref="newClassificationSelect" - v-model="selectedNewClassification" - placeholder="Add a classification" - exclude-manual - :classifications="element.classifications" - :corpus-id="element.corpus.id" - /> - </p> - <p class="control"> - <a - class="button is-primary" - :class="{ 'is-loading': isSavingNewClassification }" - :disabled="!selectedNewClassification || isSavingNewClassification || manualClassificationExists" - v-on:click="createClassification" - > - Add - </a> - </p> - </div> - <p class="help is-danger" v-if="manualClassificationExists">A manual classification for this ML class already exists.</p> + <form v-on:submit.prevent="createClassification"> + <div v-if="canWriteElement(elementId) && hasMlClasses" class="field has-addons"> + <p class="control"> + <MLClassSelect + ref="newClassificationSelect" + v-model="selectedNewClassification" + :is-valid.sync="validClassification" + placeholder="Add a classification" + exclude-manual + auto-select + :classifications="element.classifications" + :corpus-id="element.corpus.id" + /> + </p> + <p class="control"> + <button + type="button" + class="button is-primary" + :class="{ 'is-loading': isSavingNewClassification }" + :disabled="!canCreateClassification" + > + Add + </button> + </p> + </div> + <p class="help is-danger" v-if="manualClassificationExists">A manual classification for this ML class already exists.</p> + </form> <Classifications v-if="element.classifications" :element="element" /> </DropdownContent> <hr /> @@ -177,6 +181,7 @@ export default { CLASSIFICATIONS_HELP, toggleMetas: true, selectedNewClassification: '', + validClassification: null, isSavingNewClassification: false, transcriptionModal: false, deleteModal: false, @@ -203,6 +208,9 @@ export default { this.element.classifications && this.element.classifications.find(c => c.ml_class.id === this.selectedNewClassification) }, + canCreateClassification () { + return this.element && this.selectedNewClassification && !this.manualClassificationExists && !this.isSavingNewClassification + }, classifications () { return (this.element && this.element.classifications) || [] }, @@ -224,7 +232,7 @@ export default { ...mapActions('elements', ['listTranscriptions']), ...mapActions('process', ['getWorkerVersion']), async createClassification () { - if (!this.element || !this.selectedNewClassification || this.isSavingNewClassification || this.manualClassificationExists) return + if (!this.canCreateClassification) return this.isSavingNewClassification = true try { await this.$store.dispatch('classification/create', { diff --git a/vue/MLClassSelect.vue b/vue/MLClassSelect.vue index d510edda95c09e2b4f5340b6cf6fb56b46b46680..c81d9c4775d73a9f0bcd55882d063f6603660bff 100644 --- a/vue/MLClassSelect.vue +++ b/vue/MLClassSelect.vue @@ -3,8 +3,7 @@ ref="select" results-name="classes" v-bind="$attrs" - v-on:input="value => $emit('input', value)" - v-on:update:isValid="$emit('update:isValid', $event)" + v-on="$listeners" /> </template> diff --git a/vue/Navigation/CorpusSelection.vue b/vue/Navigation/CorpusSelection.vue index c85a2ffba5cfc0df25d2104dbf8db5b50e538f1c..f84ff02c665ac8f4e4e2697eadb8007d9046c789 100644 --- a/vue/Navigation/CorpusSelection.vue +++ b/vue/Navigation/CorpusSelection.vue @@ -65,6 +65,7 @@ :corpus-id="corpusId" v-model="selectedNewClassification" placeholder="ML class" + v-on:submit="createClassification" /> </div> <div v-else class="notification is-warning">No classification for this project</div> diff --git a/vue/SearchableSelect.vue b/vue/SearchableSelect.vue index b29fef195159f47086a4c0a12c1690b4c14e1048..769093055d06a386b85a657d0caa38ac15f62c39 100644 --- a/vue/SearchableSelect.vue +++ b/vue/SearchableSelect.vue @@ -5,10 +5,10 @@ ref="input" v-model="input" :placeholder="placeholder" - class="input dropdown-trigger mousetrap" + class="input dropdown-trigger" :class="inputClass" v-on:click.stop="toggleSuggestions" - v-on:keyup="navigate" + v-on:keyup.stop="navigate" v-on:input="check" /> <div @@ -143,7 +143,7 @@ export default { }, methods: { setValidInput (bool) { - // Update input validity binded prop or data + // Update input validity bound prop or data if (this.isValid !== null) this.$emit('update:isValid', bool) else this.valid = bool }, @@ -151,6 +151,18 @@ export default { return highlight(suggestion, this.input.split(/\s+/)) }, navigate (event) { + /* + * If the user presses Enter and there already is a valid input, trigger a submit event + * to imply the user is trying to submit a form. + * Do not submit if the suggestions are currently opened with a selected value, since this + * means the user is trying to just select another value. But since the suggestions can be + * displayed just by clicking, do submit if no value is selected even when they are shown. + */ + if (this.validInput && event.key === 'Enter' && (!this.toggled || !this.current)) { + this.$emit('submit', this.current) + return + } + this.toggled = true const currentIndex = Object.keys(this.suggestions).indexOf(this.current) let newIndex = currentIndex @@ -189,7 +201,8 @@ export default { const queryTerms = this.input.trim() let output try { - output = await this.getSuggestions(queryTerms) + // this.getSuggestions might not always be async; just ensure it is a promise + output = await Promise.resolve(this.getSuggestions(queryTerms)) } catch { this.suggestions = [] return