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/06/23 19:38:57 UTC

[airavata-django-portal] branch develop updated (ab9f761 -> 0590d3b)

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

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


    from ab9f761  AIRAVATA-3163 Fix scrolling of sidebar
     new bd24746  AIRAVATA-3322 Paginated experiment statistics view
     new 0590d3b  AIRAVATA-3322 Fix Pager display for results that don't return counts

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../statistics/ExperimentStatisticsContainer.vue   | 43 ++++++++++++++++------
 django_airavata/apps/api/serializers.py            | 17 +++++----
 .../django_airavata_api/js/service_config.js       |  3 ++
 .../js/utils/PaginationIterator.js                 | 11 ++++--
 django_airavata/apps/api/views.py                  | 22 ++++++++---
 .../static/common/js/components/Pager.vue          |  9 ++++-
 6 files changed, 78 insertions(+), 27 deletions(-)

[airavata-django-portal] 01/02: AIRAVATA-3322 Paginated experiment statistics view

Posted by ma...@apache.org.
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 bd2474661441528c425a4a5e049400a1baf29d27
Author: Marcus Christie <ma...@apache.org>
AuthorDate: Wed Jun 23 15:32:17 2021 -0400

    AIRAVATA-3322 Paginated experiment statistics view
---
 .../statistics/ExperimentStatisticsContainer.vue   | 43 ++++++++++++++++------
 django_airavata/apps/api/serializers.py            | 17 +++++----
 .../django_airavata_api/js/service_config.js       |  3 ++
 .../js/utils/PaginationIterator.js                 | 11 ++++--
 django_airavata/apps/api/views.py                  | 22 ++++++++---
 .../static/common/js/components/Pager.vue          |  6 +++
 6 files changed, 76 insertions(+), 26 deletions(-)

diff --git a/django_airavata/apps/admin/static/django_airavata_admin/src/components/statistics/ExperimentStatisticsContainer.vue b/django_airavata/apps/admin/static/django_airavata_admin/src/components/statistics/ExperimentStatisticsContainer.vue
index c15d0f1..8561d3c 100644
--- a/django_airavata/apps/admin/static/django_airavata_admin/src/components/statistics/ExperimentStatisticsContainer.vue
+++ b/django_airavata/apps/admin/static/django_airavata_admin/src/components/statistics/ExperimentStatisticsContainer.vue
@@ -151,7 +151,7 @@
                 header-text-variant="white"
                 :count="experimentStatistics.allExperimentCount || 0"
                 title="Total Experiments"
-                @click="selectedExperimentSummariesKey = 'allExperiments'"
+                @click="selectExperiments('allExperiments')"
               >
                 <span slot="link-text">All</span>
               </experiment-statistics-card>
@@ -162,7 +162,7 @@
                 :count="experimentStatistics.createdExperimentCount || 0"
                 :states="createdStates"
                 title="Created Experiments"
-                @click="selectedExperimentSummariesKey = 'createdExperiments'"
+                @click="selectExperiments('createdExperiments')"
               >
               </experiment-statistics-card>
             </div>
@@ -173,7 +173,7 @@
                 :count="experimentStatistics.runningExperimentCount || 0"
                 :states="runningStates"
                 title="Running Experiments"
-                @click="selectedExperimentSummariesKey = 'runningExperiments'"
+                @click="selectExperiments('runningExperiments')"
               >
               </experiment-statistics-card>
             </div>
@@ -185,7 +185,7 @@
                 :count="experimentStatistics.completedExperimentCount || 0"
                 :states="completedStates"
                 title="Completed Experiments"
-                @click="selectedExperimentSummariesKey = 'completedExperiments'"
+                @click="selectExperiments('completedExperiments')"
               >
               </experiment-statistics-card>
             </div>
@@ -197,7 +197,7 @@
                 :count="experimentStatistics.cancelledExperimentCount || 0"
                 :states="canceledStates"
                 title="Cancelled Experiments"
-                @click="selectedExperimentSummariesKey = 'cancelledExperiments'"
+                @click="selectExperiments('cancelledExperiments')"
               >
               </experiment-statistics-card>
             </div>
@@ -209,7 +209,7 @@
                 :count="experimentStatistics.failedExperimentCount || 0"
                 :states="failedStates"
                 title="Failed Experiments"
-                @click="selectedExperimentSummariesKey = 'failedExperiments'"
+                @click="selectExperiments('failedExperiments')"
               >
               </experiment-statistics-card>
             </div>
@@ -240,6 +240,12 @@
                   </template>
                 </b-table>
               </b-card>
+              <pager
+                v-if="experimentStatistics.allExperimentCount > 0"
+                :paginator="experimentStatisticsPaginator"
+                @next="experimentStatisticsPaginator.next()"
+                @previous="experimentStatisticsPaginator.previous()"
+              ></pager>
             </div>
           </div>
         </b-tab>
@@ -279,7 +285,7 @@ export default {
     const fromTime = new Date().fp_incr(0);
     const toTime = new Date().fp_incr(1);
     return {
-      experimentStatistics: {},
+      experimentStatisticsPaginator: null,
       selectedExperimentSummariesKey: null,
       fromTime: fromTime,
       toTime: toTime,
@@ -315,8 +321,14 @@ export default {
     "compute-resource-name": components.ComputeResourceName,
     "human-date": components.HumanDate,
     "experiment-status-badge": components.ExperimentStatusBadge,
+    pager: components.Pager,
   },
   computed: {
+    experimentStatistics() {
+      return this.experimentStatisticsPaginator
+        ? this.experimentStatisticsPaginator.results
+        : {};
+    },
     createdStates() {
       // TODO: moved to ExperimentStatistics model
       return [models.ExperimentState.CREATED, models.ExperimentState.VALIDATED];
@@ -475,8 +487,10 @@ export default {
       if (this.hostnameFilterEnabled && this.hostnameFilter) {
         requestData["resourceHostName"] = this.hostnameFilter;
       }
-      services.ExperimentStatisticsService.get(requestData).then(
-        (stats) => (this.experimentStatistics = stats)
+      return services.ExperimentStatisticsService.get(requestData).then(
+        (stats) => {
+          this.experimentStatisticsPaginator = stats;
+        }
       );
     },
     getPast24Hours() {
@@ -484,13 +498,11 @@ export default {
       //this.fromTime = new Date(this.fromTime.setHours(0,0,0));
       this.toTime = new Date().fp_incr(1);
       this.updateDateRange();
-      this.loadStatistics();
     },
     getPastWeek() {
       this.fromTime = new Date().fp_incr(-7);
       this.toTime = new Date().fp_incr(1);
       this.updateDateRange();
-      this.loadStatistics();
     },
     updateDateRange() {
       this.dateRange = [
@@ -552,6 +564,15 @@ export default {
     scrollTabsIntoView() {
       this.$refs.tabs.$el.scrollIntoView({ behavior: "smooth" });
     },
+    selectExperiments(experimentSummariesKey) {
+      if (
+        this.experimentStatisticsPaginator &&
+        this.experimentStatisticsPaginator.offset > 0
+      ) {
+        this.loadStatistics();
+      }
+      this.selectedExperimentSummariesKey = experimentSummariesKey;
+    },
   },
 };
 </script>
diff --git a/django_airavata/apps/api/serializers.py b/django_airavata/apps/api/serializers.py
index ec68e11..700bbf6 100644
--- a/django_airavata/apps/api/serializers.py
+++ b/django_airavata/apps/api/serializers.py
@@ -531,7 +531,7 @@ class FullExperimentSerializer(serializers.Serializer):
         raise Exception("Not implemented")
 
 
-class ExperimentSummarySerializer(
+class BaseExperimentSummarySerializer(
         thrift_utils.create_serializer_class(ExperimentSummaryModel)):
     creationTime = UTCPosixTimestampDateTimeField()
     statusUpdateTime = UTCPosixTimestampDateTimeField()
@@ -543,6 +543,9 @@ class ExperimentSummarySerializer(
         view_name='django_airavata_api:project-detail',
         lookup_field='projectId',
         lookup_url_kwarg='project_id')
+
+
+class ExperimentSummarySerializer(BaseExperimentSummarySerializer):
     userHasWriteAccess = serializers.SerializerMethodField()
 
     def get_userHasWriteAccess(self, experiment):
@@ -989,12 +992,12 @@ class NotificationSerializer(
 
 class ExperimentStatisticsSerializer(
         thrift_utils.create_serializer_class(ExperimentStatistics)):
-    allExperiments = ExperimentSummarySerializer(many=True)
-    completedExperiments = ExperimentSummarySerializer(many=True)
-    failedExperiments = ExperimentSummarySerializer(many=True)
-    cancelledExperiments = ExperimentSummarySerializer(many=True)
-    createdExperiments = ExperimentSummarySerializer(many=True)
-    runningExperiments = ExperimentSummarySerializer(many=True)
+    allExperiments = BaseExperimentSummarySerializer(many=True)
+    completedExperiments = BaseExperimentSummarySerializer(many=True)
+    failedExperiments = BaseExperimentSummarySerializer(many=True)
+    cancelledExperiments = BaseExperimentSummarySerializer(many=True)
+    createdExperiments = BaseExperimentSummarySerializer(many=True)
+    runningExperiments = BaseExperimentSummarySerializer(many=True)
 
 
 class UnverifiedEmailUserProfile(serializers.Serializer):
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 4d5d39b..64ad6b1 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
@@ -218,7 +218,10 @@ export default {
           "userName",
           "applicationName",
           "resourceHostName",
+          "limit",
+          "offset",
         ],
+        pagination: true,
         modelClass: ExperimentStatistics,
       },
     },
diff --git a/django_airavata/apps/api/static/django_airavata_api/js/utils/PaginationIterator.js b/django_airavata/apps/api/static/django_airavata_api/js/utils/PaginationIterator.js
index 5ea87e0..e98a653 100644
--- a/django_airavata/apps/api/static/django_airavata_api/js/utils/PaginationIterator.js
+++ b/django_airavata/apps/api/static/django_airavata_api/js/utils/PaginationIterator.js
@@ -30,14 +30,19 @@ export default class PaginationIterator {
     this._next = pagedResponse.next;
     this._previous = pagedResponse.previous;
     if (this.resultType) {
-      this.results = pagedResponse.results.map(
-        (result) => new this.resultType(result)
-      );
+      if (Array.isArray(pagedResponse.results)) {
+        this.results = pagedResponse.results.map(
+          (result) => new this.resultType(result)
+        );
+      } else {
+        this.results = new this.resultType(pagedResponse.results);
+      }
     } else {
       this.results = pagedResponse.results;
     }
     this.offset = pagedResponse.offset;
     this.limit = pagedResponse.limit;
+    this.count = pagedResponse.count;
     return this;
   }
 
diff --git a/django_airavata/apps/api/views.py b/django_airavata/apps/api/views.py
index 675236c..a33f7a9 100644
--- a/django_airavata/apps/api/views.py
+++ b/django_airavata/apps/api/views.py
@@ -30,7 +30,7 @@ from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
 from django.http import FileResponse, Http404, HttpResponse, JsonResponse
 from django.urls import reverse
 from django.views.decorators.gzip import gzip_page
-from rest_framework import mixins, status
+from rest_framework import mixins, pagination, status
 from rest_framework.decorators import action, api_view
 from rest_framework.exceptions import ParseError
 from rest_framework.renderers import JSONRenderer
@@ -1832,12 +1832,24 @@ class ExperimentStatisticsView(APIView):
         username = request.GET.get('userName', None)
         application_name = request.GET.get('applicationName', None)
         resource_hostname = request.GET.get('resourceHostName', None)
+        limit = int(request.GET.get('limit', '50'))
+        offset = int(request.GET.get('offset', '0'))
+
         statistics = request.airavata_client.getExperimentStatistics(
             request.authz_token, settings.GATEWAY_ID, from_time, to_time,
-            username, application_name, resource_hostname)
-        serializer = self.serializer_class(
-            statistics, context={'request': request})
-        return Response(serializer.data)
+            username, application_name, resource_hostname, limit, offset)
+        serializer = self.serializer_class(statistics, context={'request': request})
+
+        paginator = pagination.LimitOffsetPagination()
+        paginator.count = statistics.allExperimentCount
+        paginator.limit = limit
+        paginator.offset = offset
+        paginator.request = request
+        response = paginator.get_paginated_response(serializer.data)
+        # Also add limit and offset to the response
+        response.data['limit'] = limit
+        response.data['offset'] = offset
+        return response
 
 
 class UnverifiedEmailUserViewSet(mixins.ListModelMixin,
diff --git a/django_airavata/static/common/js/components/Pager.vue b/django_airavata/static/common/js/components/Pager.vue
index 4d49aaf..69005e4 100644
--- a/django_airavata/static/common/js/components/Pager.vue
+++ b/django_airavata/static/common/js/components/Pager.vue
@@ -42,6 +42,12 @@ export default {
     },
     last: function () {
       if (this.paginator) {
+        if (this.paginator.hasOwnProperty("count")) {
+          return Math.min(
+            this.paginator.offset + this.paginator.limit,
+            this.paginator.count
+          );
+        }
         return this.paginator.offset + this.paginator.results.length;
       } else {
         return null;

[airavata-django-portal] 02/02: AIRAVATA-3322 Fix Pager display for results that don't return counts

Posted by ma...@apache.org.
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 0590d3ba289b8bd131bfb2bde1690be270bd6d31
Author: Marcus Christie <ma...@apache.org>
AuthorDate: Wed Jun 23 15:37:19 2021 -0400

    AIRAVATA-3322 Fix Pager display for results that don't return counts
---
 django_airavata/static/common/js/components/Pager.vue | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/django_airavata/static/common/js/components/Pager.vue b/django_airavata/static/common/js/components/Pager.vue
index 69005e4..06c0316 100644
--- a/django_airavata/static/common/js/components/Pager.vue
+++ b/django_airavata/static/common/js/components/Pager.vue
@@ -42,13 +42,14 @@ export default {
     },
     last: function () {
       if (this.paginator) {
-        if (this.paginator.hasOwnProperty("count")) {
+        if (this.paginator.count) {
           return Math.min(
             this.paginator.offset + this.paginator.limit,
             this.paginator.count
           );
+        } else {
+          return this.paginator.offset + this.paginator.results.length;
         }
-        return this.paginator.offset + this.paginator.results.length;
       } else {
         return null;
       }