You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by ma...@apache.org on 2020/05/12 22:45:30 UTC
[airavata-django-portal] 01/04: AIRAVATA-3324 Add
AutocompleteInputEditor
This is an automated email from the ASF dual-hosted git repository.
machristie pushed a commit to branch AIRAVATA-3324-custom-input-editor-autocomplete-input-editor
in repository https://gitbox.apache.org/repos/asf/airavata-django-portal.git
commit 738ad5d027b1b42eb308f7a7cab10e22cf5f71dd
Author: Marcus Christie <ma...@apache.org>
AuthorDate: Mon Apr 27 16:04:35 2020 -0400
AIRAVATA-3324 Add AutocompleteInputEditor
---
.../input-editors/AutocompleteInputEditor.vue | 126 +++++++++++++++++++++
.../input-editors/InputEditorContainer.vue | 4 +-
.../common/js/components/AutocompleteTextInput.vue | 9 +-
3 files changed, 136 insertions(+), 3 deletions(-)
diff --git a/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/input-editors/AutocompleteInputEditor.vue b/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/input-editors/AutocompleteInputEditor.vue
new file mode 100644
index 0000000..067bb24
--- /dev/null
+++ b/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/input-editors/AutocompleteInputEditor.vue
@@ -0,0 +1,126 @@
+<template>
+ <!-- TODO: replace with better display and x to clear out selected value -->
+ <div v-if="value">
+ {{ text }}
+ <b-link @click="cancel">Cancel</b-link>
+ </div>
+ <div v-else>
+ <autocomplete-text-input
+ :suggestions="suggestions"
+ @selected="selected"
+ @search-changed="searchChanged"
+ :max-matches="10"
+ />
+ </div>
+</template>
+
+<script>
+import { utils } from "django-airavata-api";
+import { InputEditorMixin } from "django-airavata-workspace-plugin-api";
+import { components } from "django-airavata-common-ui";
+
+export default {
+ name: "autocomplete-input-editor",
+ mixins: [InputEditorMixin],
+ components: {
+ "autocomplete-text-input": components.AutocompleteTextInput
+ },
+ props: {
+ value: {
+ type: String
+ }
+ },
+ data() {
+ return {
+ text: null,
+ searchString: "",
+ searchResults: null,
+ lastUpdate: Date.now()
+ };
+ },
+ computed: {
+ suggestions() {
+ return this.searchResults
+ ? this.searchResults.results.map(r => {
+ return {
+ id: r.value,
+ name: r.text
+ };
+ })
+ : [];
+ },
+ autocompleteUrl() {
+ if (
+ this.experimentInput.editorConfig &&
+ "url" in this.experimentInput.editorConfig
+ ) {
+ return this.experimentInput.editorConfig.url;
+ } else {
+ // eslint-disable-next-line no-console
+ console.warn(
+ "editor config is missing 'url'. Make sure input " +
+ this.experimentInput.name +
+ " has metadata configuration something like:\n" +
+ JSON.stringify(
+ {
+ editor: {
+ "ui-component-id": "autocomplete-input-editor",
+ config: {
+ url: "/some/custom/search/"
+ }
+ }
+ },
+ null,
+ 4
+ )
+ );
+ return null;
+ }
+ }
+ },
+ methods: {
+ loadTextForValue(value) {
+ if (this.autocompleteUrl) {
+ return utils.FetchUtils.get(this.autocompleteUrl, {
+ id: value
+ }).then(resp => resp.text);
+ } else {
+ return Promise.resolve(null);
+ }
+ },
+ cancel() {
+ this.data = null;
+ this.valueChanged();
+ },
+ selected(suggestion) {
+ this.data = suggestion.id;
+ this.text = suggestion.name;
+ this.valueChanged();
+ },
+ searchChanged(newValue) {
+ this.searchString = newValue;
+ const currentTime = Date.now();
+ if (this.autocompleteUrl) {
+ utils.FetchUtils.get(
+ this.autocompleteUrl,
+ {
+ search: this.searchString
+ },
+ { showSpinner: false }
+ ).then(resp => {
+ // Prevent older responses from overwriting newer ones
+ if (currentTime > this.lastUpdate) {
+ this.searchResults = resp;
+ this.lastUpdate = currentTime;
+ }
+ });
+ }
+ }
+ },
+ created() {
+ if (this.value) {
+ this.loadTextForValue(this.value).then(text => (this.text = text));
+ }
+ }
+};
+</script>
diff --git a/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/input-editors/InputEditorContainer.vue b/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/input-editors/InputEditorContainer.vue
index 44b4489..afb7571 100644
--- a/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/input-editors/InputEditorContainer.vue
+++ b/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/input-editors/InputEditorContainer.vue
@@ -17,6 +17,7 @@
<script>
import UserFileInputEditor from "./UserFileInputEditor.vue";
+import AutocompleteInputEditor from "./AutocompleteInputEditor";
import CheckboxInputEditor from "./CheckboxInputEditor.vue";
import FileInputEditor from './FileInputEditor.vue'
import InputEditorFormGroup from './InputEditorFormGroup.vue'
@@ -43,8 +44,8 @@ export default {
}
},
components: {
+ AutocompleteInputEditor,
CheckboxInputEditor,
- UserFileInputEditor,
FileInputEditor,
InputEditorFormGroup,
MultiFileInputEditor,
@@ -52,6 +53,7 @@ export default {
SelectInputEditor,
StringInputEditor,
TextareaInputEditor,
+ UserFileInputEditor,
},
created() {
if (!this.show) {
diff --git a/django_airavata/static/common/js/components/AutocompleteTextInput.vue b/django_airavata/static/common/js/components/AutocompleteTextInput.vue
index 59071e6..5579af0 100644
--- a/django_airavata/static/common/js/components/AutocompleteTextInput.vue
+++ b/django_airavata/static/common/js/components/AutocompleteTextInput.vue
@@ -8,7 +8,7 @@
@keydown.native.down='down' @keydown.native.up='up'></b-form-input>
</b-input-group>
<b-list-group class="autocomplete-suggestion-list" v-if="open">
- <b-list-group-item v-for="(suggestion, index) in filtered.slice(0,5)" v-bind:class="{'active': isActive(index)}" href="#"
+ <b-list-group-item v-for="(suggestion, index) in filtered" v-bind:class="{'active': isActive(index)}" href="#"
@click="suggestionClick(index)" v-bind:key="suggestion.id">
<slot name="suggestion" :suggestion="suggestion">
{{ suggestion.name }}
@@ -29,6 +29,10 @@ export default {
placeholder: {
type: String,
default: "Type to get suggestions..."
+ },
+ maxMatches: {
+ type: Number,
+ default: 5
}
},
data() {
@@ -46,7 +50,7 @@ export default {
return (
data.name.toLowerCase().indexOf(this.searchValue.toLowerCase()) >= 0
);
- }).slice(0,5);
+ }).slice(0,this.maxMatches);
}
},
methods: {
@@ -59,6 +63,7 @@ export default {
this.open = false;
}
this.searchValue = value;
+ this.$emit('search-changed', value);
},
enter() {
if (this.filtered.length === 0) {