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/07/08 19:19:43 UTC

[airavata-django-portal] 02/05: AIRAVATA-3567 Support saving all ext user profile values in one REST call

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 feb1d8c3d8c005471a7404309b00423a24bc2b0f
Author: Marcus Christie <ma...@apache.org>
AuthorDate: Tue Jun 14 17:15:45 2022 -0400

    AIRAVATA-3567 Support saving all ext user profile values in one REST call
---
 .../js/models/ExtendedUserProfileValue.js          | 27 ++++++++++++++++++++++
 .../django_airavata_api/js/service_config.js       | 10 ++++++++
 .../js/services/ServiceFactory.js                  |  3 +++
 django_airavata/apps/auth/serializers.py           |  8 +++++++
 .../js/store/modules/extendedUserProfile.js        | 21 ++++++-----------
 django_airavata/apps/auth/views.py                 | 16 +++++++++++++
 6 files changed, 71 insertions(+), 14 deletions(-)

diff --git a/django_airavata/apps/api/static/django_airavata_api/js/models/ExtendedUserProfileValue.js b/django_airavata/apps/api/static/django_airavata_api/js/models/ExtendedUserProfileValue.js
index bb417a6d..02618cb0 100644
--- a/django_airavata/apps/api/static/django_airavata_api/js/models/ExtendedUserProfileValue.js
+++ b/django_airavata/apps/api/static/django_airavata_api/js/models/ExtendedUserProfileValue.js
@@ -16,4 +16,31 @@ export default class ExtendedUserProfileValue extends BaseModel {
   constructor(data = {}) {
     super(FIELDS, data);
   }
+
+  toJSON() {
+    const copy = Object.assign({}, this);
+    // Remove unnecessary properties
+    switch (this.value_type) {
+      case "text":
+        delete copy["other_value"];
+        delete copy["choices"];
+        delete copy["agreement_value"];
+        break;
+      case "single_choice":
+      case "multi_choice":
+        delete copy["text_value"];
+        delete copy["agreement_value"];
+        break;
+      case "user_agreement":
+        delete copy["text_value"];
+        delete copy["other_value"];
+        delete copy["choices"];
+        break;
+      default:
+        // eslint-disable-next-line no-console
+        console.error("Unrecognized value type", this.value_type);
+        break;
+    }
+    return copy;
+  }
 }
diff --git a/django_airavata/apps/api/static/django_airavata_api/js/service_config.js b/django_airavata/apps/api/static/django_airavata_api/js/service_config.js
index bef3bfe0..13aba7ca 100644
--- a/django_airavata/apps/api/static/django_airavata_api/js/service_config.js
+++ b/django_airavata/apps/api/static/django_airavata_api/js/service_config.js
@@ -249,6 +249,16 @@ export default {
     viewSet: true,
     modelClass: ExtendedUserProfileValue,
     queryParams: ["username"],
+    methods: {
+      saveAll: {
+        url: "/auth/extended-user-profile-values/save-all/",
+        requestType: "post",
+        modelClass: ExtendedUserProfileValue,
+        bodyParams: {
+          name: "data",
+        },
+      },
+    },
   },
   FullExperiments: {
     url: "/api/full-experiments",
diff --git a/django_airavata/apps/api/static/django_airavata_api/js/services/ServiceFactory.js b/django_airavata/apps/api/static/django_airavata_api/js/services/ServiceFactory.js
index 5aa1e61b..29bf84af 100644
--- a/django_airavata/apps/api/static/django_airavata_api/js/services/ServiceFactory.js
+++ b/django_airavata/apps/api/static/django_airavata_api/js/services/ServiceFactory.js
@@ -274,6 +274,9 @@ class ServiceFactory {
           }
         };
         let resultHandler = (data) => {
+          if (Array.isArray(data)) {
+            return data.map((item) => resultHandler(item));
+          }
           return config.modelClass ? new config.modelClass(data) : data;
         };
         switch (config.requestType.toLowerCase()) {
diff --git a/django_airavata/apps/auth/serializers.py b/django_airavata/apps/auth/serializers.py
index dbafa415..70db769c 100644
--- a/django_airavata/apps/auth/serializers.py
+++ b/django_airavata/apps/auth/serializers.py
@@ -226,6 +226,7 @@ class ExtendedUserProfileFieldSerializer(serializers.ModelSerializer):
 
 
 class ExtendedUserProfileValueSerializer(serializers.ModelSerializer):
+    id = serializers.IntegerField(label='ID', required=False)
     text_value = serializers.CharField(required=False, allow_blank=True)
     choices = serializers.ListField(child=serializers.IntegerField(), required=False)
     other_value = serializers.CharField(required=False, allow_blank=True)
@@ -259,6 +260,13 @@ class ExtendedUserProfileValueSerializer(serializers.ModelSerializer):
         user = request.user
         user_profile = user.user_profile
 
+        # Support create/update in the many=True situation. When many=True and
+        # .save() is called, .create() will be called on each value. Here we
+        # need to see if there is an id and if so call .update() instead.
+        if "id" in validated_data:
+            instance = models.ExtendedUserProfileValue.objects.get(id=validated_data["id"])
+            return self.update(instance, validated_data)
+
         ext_user_profile_field = validated_data.pop('ext_user_profile_field')
         if ext_user_profile_field.field_type == 'text':
             text_value = validated_data.pop('text_value')
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 9fef5c74..084731b4 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
@@ -64,20 +64,10 @@ const actions = {
     commit("setExtendedUserProfileValues", { extendedUserProfileValues });
   },
   async saveExtendedUserProfileValues({ state, commit }) {
-    for (const value of state.extendedUserProfileValues) {
-      // Create or update each value
-      if (value.id) {
-        await services.ExtendedUserProfileValueService.update({
-          lookup: value.id,
-          data: value,
-        });
-      } else {
-        const extendedUserProfileValue = await services.ExtendedUserProfileValueService.create(
-          { data: value }
-        );
-        commit("updateExtendedUserProfileValue", { extendedUserProfileValue });
-      }
-    }
+    const extendedUserProfileValues = await services.ExtendedUserProfileValueService.saveAll(
+      { data: state.extendedUserProfileValues }
+    );
+    commit("updateExtendedUserProfileValues", { extendedUserProfileValues });
   },
 };
 
@@ -184,6 +174,9 @@ const mutations = {
     );
     state.extendedUserProfileValues.splice(index, 1, extendedUserProfileValue);
   },
+  updateExtendedUserProfileValues(state, { extendedUserProfileValues }) {
+    state.extendedUserProfileValues = extendedUserProfileValues;
+  },
 };
 
 export default {
diff --git a/django_airavata/apps/auth/views.py b/django_airavata/apps/auth/views.py
index 95520b42..eb016607 100644
--- a/django_airavata/apps/auth/views.py
+++ b/django_airavata/apps/auth/views.py
@@ -749,3 +749,19 @@ class ExtendedUserProfileValueViewset(mixins.CreateModelMixin,
         else:
             queryset = user.user_profile.extended_profile.all()
         return queryset
+
+    @action(methods=['POST'], detail=False, url_path="save-all")
+    def save_all(self, request, format=None):
+        user = request.user
+        user_profile: models.UserProfile = user.user_profile
+        old_valid = user_profile.is_ext_user_profile_valid
+        serializer: serializers.ExtendedUserProfileValueSerializer = self.get_serializer(data=request.data, many=True)
+        serializer.is_valid(raise_exception=True)
+        values = serializer.save()
+
+        new_valid = user_profile.is_ext_user_profile_valid
+        if not old_valid and new_valid:
+            logger.info("TODO: send email to admin")
+
+        serializer = self.get_serializer(values, many=True)
+        return Response(serializer.data)