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 2022/04/26 20:09:00 UTC

[airavata-django-portal] 06/06: AIRAVATA-3565 Other field for single and multi choice fields

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

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

commit 793b8f39c6df177259babd0e190892513335d9c5
Author: Marcus Christie <ma...@apache.org>
AuthorDate: Tue Apr 26 15:38:57 2022 -0400

    AIRAVATA-3565 Other field for single and multi choice fields
---
 .../ExtendedUserProfileMultiChoiceFieldEditor.vue  | 61 ++++++++++++++++++++--
 .../ExtendedUserProfileSingleChoiceFieldEditor.vue | 60 +++++++++++++++++++--
 .../js/store/modules/extendedUserProfile.js        | 46 +++++++++++++++-
 3 files changed, 156 insertions(+), 11 deletions(-)

diff --git a/django_airavata/apps/auth/static/django_airavata_auth/js/components/ExtendedUserProfileMultiChoiceFieldEditor.vue b/django_airavata/apps/auth/static/django_airavata_auth/js/components/ExtendedUserProfileMultiChoiceFieldEditor.vue
index d83872e7..db45cbb9 100644
--- a/django_airavata/apps/auth/static/django_airavata_auth/js/components/ExtendedUserProfileMultiChoiceFieldEditor.vue
+++ b/django_airavata/apps/auth/static/django_airavata_auth/js/components/ExtendedUserProfileMultiChoiceFieldEditor.vue
@@ -4,29 +4,70 @@
       v-model="value"
       :options="options"
       stacked
-    ></b-form-checkbox-group>
+      @change="onChange"
+    >
+      <b-form-checkbox :value="otherOptionValue"
+        >Other (please specify)</b-form-checkbox
+      >
+    </b-form-checkbox-group>
+    <b-form-input
+      class="mt-2"
+      v-if="showOther"
+      v-model="other"
+      placeholder="Please specify"
+    />
   </extended-user-profile-field-editor>
 </template>
 
 <script>
 import { mapGetters, mapMutations } from "vuex";
 import ExtendedUserProfileFieldEditor from "./ExtendedUserProfileFieldEditor.vue";
+const OTHER_OPTION = new Object(); // sentinel value
 export default {
   components: { ExtendedUserProfileFieldEditor },
   props: ["extendedUserProfileField"],
+  data() {
+    return {
+      otherOptionSelected: false,
+    };
+  },
   computed: {
-    ...mapGetters("extendedUserProfile", ["getMultiChoiceValue"]),
+    ...mapGetters("extendedUserProfile", [
+      "getMultiChoiceValue",
+      "getMultiChoiceOther",
+    ]),
     value: {
       get() {
-        return this.getMultiChoiceValue(this.extendedUserProfileField.id);
+        const copy = this.getMultiChoiceValue(
+          this.extendedUserProfileField.id
+        ).slice();
+        if (this.showOther) {
+          copy.push(this.otherOptionValue);
+        }
+        return copy;
       },
       set(value) {
+        const values = value.filter((v) => v !== this.otherOptionValue);
         this.setMultiChoiceValue({
+          value: values,
+          id: this.extendedUserProfileField.id,
+        });
+      },
+    },
+    other: {
+      get() {
+        return this.getMultiChoiceOther(this.extendedUserProfileField.id);
+      },
+      set(value) {
+        this.setMultiChoiceOther({
           value,
           id: this.extendedUserProfileField.id,
         });
       },
     },
+    showOther() {
+      return this.other || this.otherOptionSelected;
+    },
     options() {
       return this.extendedUserProfileField &&
         this.extendedUserProfileField.choices
@@ -38,9 +79,21 @@ export default {
           })
         : [];
     },
+    otherOptionValue() {
+      return OTHER_OPTION;
+    },
   },
   methods: {
-    ...mapMutations("extendedUserProfile", ["setMultiChoiceValue"]),
+    ...mapMutations("extendedUserProfile", [
+      "setMultiChoiceValue",
+      "setMultiChoiceOther",
+    ]),
+    onChange(value) {
+      this.otherOptionSelected = value.includes(this.otherOptionValue);
+      if (!this.otherOptionSelected) {
+        this.other = "";
+      }
+    },
   },
 };
 </script>
diff --git a/django_airavata/apps/auth/static/django_airavata_auth/js/components/ExtendedUserProfileSingleChoiceFieldEditor.vue b/django_airavata/apps/auth/static/django_airavata_auth/js/components/ExtendedUserProfileSingleChoiceFieldEditor.vue
index a78fc028..524fee70 100644
--- a/django_airavata/apps/auth/static/django_airavata_auth/js/components/ExtendedUserProfileSingleChoiceFieldEditor.vue
+++ b/django_airavata/apps/auth/static/django_airavata_auth/js/components/ExtendedUserProfileSingleChoiceFieldEditor.vue
@@ -1,28 +1,69 @@
 <template>
   <extended-user-profile-field-editor v-bind="$props">
-    <b-form-select v-model="value" :options="options"></b-form-select>
+    <b-form-select v-model="value" :options="options" @change="onChange">
+      <b-form-select-option :value="otherOptionValue"
+        >Other (please specify)</b-form-select-option
+      >
+    </b-form-select>
+    <b-form-input
+      class="mt-2"
+      v-if="showOther"
+      v-model="other"
+      placeholder="Please specify"
+    />
   </extended-user-profile-field-editor>
 </template>
 
 <script>
 import { mapGetters, mapMutations } from "vuex";
 import ExtendedUserProfileFieldEditor from "./ExtendedUserProfileFieldEditor.vue";
+const OTHER_OPTION = new Object(); // sentinel value
+
 export default {
   components: { ExtendedUserProfileFieldEditor },
   props: ["extendedUserProfileField"],
+  data() {
+    return {
+      otherOptionSelected: false,
+    };
+  },
   computed: {
-    ...mapGetters("extendedUserProfile", ["getSingleChoiceValue"]),
+    ...mapGetters("extendedUserProfile", [
+      "getSingleChoiceValue",
+      "getSingleChoiceOther",
+    ]),
     value: {
       get() {
-        return this.getSingleChoiceValue(this.extendedUserProfileField.id);
+        if (this.showOther) {
+          return this.otherOptionValue;
+        } else {
+          return this.getSingleChoiceValue(this.extendedUserProfileField.id);
+        }
+      },
+      set(value) {
+        if (value !== this.otherOptionValue) {
+          this.setSingleChoiceValue({
+            value,
+            id: this.extendedUserProfileField.id,
+          });
+        }
+      },
+    },
+    other: {
+      get() {
+        return this.getSingleChoiceOther(this.extendedUserProfileField.id);
       },
       set(value) {
-        this.setSingleChoiceValue({
+        this.setSingleChoiceOther({
           value,
           id: this.extendedUserProfileField.id,
         });
       },
     },
+    showOther() {
+      const value = this.getSingleChoiceValue(this.extendedUserProfileField.id);
+      return (value === null && this.other) || this.otherOptionSelected;
+    },
     options() {
       return this.extendedUserProfileField &&
         this.extendedUserProfileField.choices
@@ -34,9 +75,18 @@ export default {
           })
         : [];
     },
+    otherOptionValue() {
+      return OTHER_OPTION;
+    },
   },
   methods: {
-    ...mapMutations("extendedUserProfile", ["setSingleChoiceValue"]),
+    ...mapMutations("extendedUserProfile", [
+      "setSingleChoiceValue",
+      "setSingleChoiceOther",
+    ]),
+    onChange(value) {
+      this.otherOptionSelected = value === this.otherOptionValue;
+    },
   },
 };
 </script>
diff --git a/django_airavata/apps/auth/static/django_airavata_auth/js/store/modules/extendedUserProfile.js b/django_airavata/apps/auth/static/django_airavata_auth/js/store/modules/extendedUserProfile.js
index b58e9ca4..d2163890 100644
--- a/django_airavata/apps/auth/static/django_airavata_auth/js/store/modules/extendedUserProfile.js
+++ b/django_airavata/apps/auth/static/django_airavata_auth/js/store/modules/extendedUserProfile.js
@@ -24,6 +24,12 @@ const getters = {
       return null;
     }
   },
+  getSingleChoiceOther: (state) => (id) => {
+    const value = state.extendedUserProfileValues.find(
+      (v) => v.ext_user_profile_field === id
+    );
+    return value ? value.other_value : null;
+  },
   getMultiChoiceValue: (state) => (id) => {
     const value = state.extendedUserProfileValues.find(
       (v) => v.ext_user_profile_field === id
@@ -31,9 +37,15 @@ const getters = {
     if (value && value.choices) {
       return value.choices;
     } else {
-      return null;
+      return [];
     }
   },
+  getMultiChoiceOther: (state) => (id) => {
+    const value = state.extendedUserProfileValues.find(
+      (v) => v.ext_user_profile_field === id
+    );
+    return value ? value.other_value : null;
+  },
   getUserAgreementValue: (state) => (id) => {
     const value = state.extendedUserProfileValues.find(
       (v) => v.ext_user_profile_field === id
@@ -105,13 +117,28 @@ const mutations = {
       });
     }
   },
+  setSingleChoiceOther(state, { value, id }) {
+    const profileValue = state.extendedUserProfileValues.find(
+      (v) => v.ext_user_profile_field === id
+    );
+    if (profileValue) {
+      profileValue.choices = [];
+      profileValue.other_value = value;
+    } else {
+      state.extendedUserProfileValues.push({
+        value_type: "single_choice",
+        ext_user_profile_field: id,
+        choices: [],
+        other_value: value,
+      });
+    }
+  },
   setMultiChoiceValue(state, { value, id }) {
     const profileValue = state.extendedUserProfileValues.find(
       (v) => v.ext_user_profile_field === id
     );
     if (profileValue) {
       profileValue.choices = value;
-      profileValue.other_value = "";
     } else {
       state.extendedUserProfileValues.push({
         value_type: "multi_choice",
@@ -120,6 +147,21 @@ const mutations = {
       });
     }
   },
+  setMultiChoiceOther(state, { value, id }) {
+    const profileValue = state.extendedUserProfileValues.find(
+      (v) => v.ext_user_profile_field === id
+    );
+    if (profileValue) {
+      profileValue.other_value = value;
+    } else {
+      state.extendedUserProfileValues.push({
+        value_type: "multi_choice",
+        ext_user_profile_field: id,
+        choices: [],
+        other_value: value,
+      });
+    }
+  },
   setUserAgreementValue(state, { value, id }) {
     const profileValue = state.extendedUserProfileValues.find(
       (v) => v.ext_user_profile_field === id