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 2021/10/05 19:47:12 UTC

[airavata-django-portal] 01/24: AIRAVATA-3477 StringInputEditor web component

This is an automated email from the ASF dual-hosted git repository.

machristie pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/airavata-django-portal.git

commit 1b923ad8c2f5d511a72d6d57a2e71072d33da169
Author: Marcus Christie <ma...@apache.org>
AuthorDate: Fri Jul 9 16:09:29 2021 -0400

    AIRAVATA-3477 StringInputEditor web component
---
 django_airavata/apps/workspace/package.json        |  4 +-
 .../js/web-components/ExperimentEditor.vue         | 20 +++++--
 .../input-editors/StringInputEditor.vue            | 62 ++++++++++++++++++++++
 3 files changed, 79 insertions(+), 7 deletions(-)

diff --git a/django_airavata/apps/workspace/package.json b/django_airavata/apps/workspace/package.json
index 0e61e88..1eb2f74 100644
--- a/django_airavata/apps/workspace/package.json
+++ b/django_airavata/apps/workspace/package.json
@@ -14,8 +14,8 @@
     "test:unit": "vue-cli-service test:unit",
     "test:unit:watch": "vue-cli-service test:unit --watch",
     "format": "prettier --write .",
-    "build:wc": "cross-env WC_MODE='true' vue-cli-service build --target wc --inline-vue --name adpf './static/django_airavata_workspace/js/web-components/*.vue' --dest ./static/django_airavata_workspace/wc",
-    "build:wc:watch": "cross-env WC_MODE='true' vue-cli-service build --target wc --inline-vue --name adpf './static/django_airavata_workspace/js/web-components/*.vue' --dest ./static/django_airavata_workspace/wc --watch"
+    "build:wc": "cross-env WC_MODE='true' vue-cli-service build --target wc --inline-vue --name adpf './static/django_airavata_workspace/js/web-components/**/*.vue' --dest ./static/django_airavata_workspace/wc",
+    "build:wc:watch": "cross-env WC_MODE='true' vue-cli-service build --target wc --inline-vue --name adpf './static/django_airavata_workspace/js/web-components/**/*.vue' --dest ./static/django_airavata_workspace/wc --watch"
   },
   "dependencies": {
     "@fortawesome/fontawesome-svg-core": "^1.2.35",
diff --git a/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/ExperimentEditor.vue b/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/ExperimentEditor.vue
index 816bdd7..4067db2 100644
--- a/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/ExperimentEditor.vue
+++ b/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/ExperimentEditor.vue
@@ -12,7 +12,7 @@
       <div
         :ref="input.name"
         :key="input.name"
-        @input="updateInputValue(input.name, $event.target.value)"
+        @input="updateInputValue(input.name, $event)"
       >
         <!-- programmatically define slots as native slots (not Vue slots), see #mounted() -->
       </div>
@@ -36,6 +36,7 @@ import {
   getExperiment,
   launchExperiment,
 } from "./store";
+import { utils } from "django-airavata-common-ui";
 
 import Vue from "vue";
 import { BootstrapVue } from "bootstrap-vue";
@@ -71,13 +72,15 @@ export default {
         slot.setAttribute("name", input.name);
         if (input.type.name === "STRING") {
           slot.textContent = `${input.name} `;
-          const textInput = document.createElement("input");
-          textInput.setAttribute("type", "text");
+          const textInput = document.createElement("adpf-string-input-editor");
           textInput.setAttribute("value", input.value);
           slot.appendChild(textInput);
+          this.$refs[input.name][0].append(slot);
+          textInput.experimentInput = input;
+          textInput.experiment = this.experiment;
+          textInput.id = utils.sanitizeHTMLId(input.name);
         }
         // TODO: add support for other input types
-        this.$refs[input.name][0].append(slot);
       }
 
       /*
@@ -188,10 +191,17 @@ export default {
     updateExperimentName(event) {
       this.experiment.experimentName = event.target.value;
     },
-    updateInputValue(inputName, value) {
+    updateInputValue(inputName, event) {
+      if (event.inputType) {
+        // Ignore these fine-grained events about the type of change made
+        return;
+      }
       const experimentInput = this.experiment.experimentInputs.find(
         (i) => i.name === inputName
       );
+      // web component input events have the current value in a detail array,
+      // native input events have the current value in target.value
+      const value = Array.isArray(event.detail) ? event.detail[0] : event.target.value;
       experimentInput.value = value;
     },
     updateProjectId(event) {
diff --git a/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/input-editors/StringInputEditor.vue b/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/input-editors/StringInputEditor.vue
new file mode 100644
index 0000000..905469e
--- /dev/null
+++ b/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/input-editors/StringInputEditor.vue
@@ -0,0 +1,62 @@
+<template>
+<!-- NOTE: regarding v-if="ready": experimentInput/experiment/id are late bound,
+     don't create component until they is available -->
+  <string-input-editor
+    v-if="ready"
+    :id="id"
+    :value="data"
+    :experiment-input="experimentInput"
+    :experiment="experiment"
+    :read-only="readOnly"
+    @input="onInput"
+  />
+</template>
+
+<script>
+import StringInputEditor from "../../components/experiment/input-editors/StringInputEditor.vue";
+import Vue from "vue";
+import { BootstrapVue } from "bootstrap-vue";
+import AsyncComputed from "vue-async-computed";
+Vue.use(BootstrapVue);
+Vue.use(AsyncComputed);
+
+export default {
+  props: {
+    value: String,
+    experimentInput: Object,
+    experiment: Object,
+    readOnly: Boolean,
+    id: String,
+  },
+  components: {
+    StringInputEditor,
+  },
+  data() {
+    return {
+      data: this.value,
+    };
+  },
+  computed: {
+    ready() {
+      return this.experiment && this.experimentInput && this.id;
+    }
+  },
+  methods: {
+    onInput(value) {
+      if (value !== this.data) {
+        this.data = value;
+        const inputEvent = new CustomEvent("input", {
+          detail: [this.data],
+          composed: true,
+          bubbles: true,
+        });
+        this.$el.dispatchEvent(inputEvent);
+      }
+    }
+  },
+};
+</script>
+
+<style>
+@import "../styles.css";
+</style>