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 2019/06/17 14:23:15 UTC

[airavata-django-portal] 02/11: AIRAVATA-2990 Display experiments for selected status category

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

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

commit 706d83983e165381e4bd9fba51d01893c5e1a3cf
Author: Marcus Christie <ma...@apache.org>
AuthorDate: Thu Jun 6 15:48:05 2019 -0400

    AIRAVATA-2990 Display experiments for selected status category
---
 .../statistics/ExperimentStatisticsContainer.vue   | 96 +++++++++++++++++++++-
 django_airavata/apps/api/views.py                  |  2 +-
 .../experiment/ExperimentStatusBadge.vue           | 33 --------
 .../js/containers/ExperimentListContainer.vue      |  4 +-
 .../js/containers/RecentExperimentsContainer.vue   |  3 +-
 .../common/js/components/ApplicationName.vue       | 40 +++++++++
 .../common/js/components/ComputeResourceName.vue   | 38 +++++++++
 .../common/js/components/ExperimentStatusBadge.vue | 38 +++++++++
 django_airavata/static/common/js/index.js          | 16 ++--
 9 files changed, 220 insertions(+), 50 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 803460a..0a20b76 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
@@ -12,6 +12,7 @@
           header-text-variant="white"
           :count="experimentStatistics.allExperimentCount || 0"
           title="Total Experiments"
+          @click="selectExperiments(experimentStatistics.allExperiments)"
         >
           <span slot="link-text">All</span>
         </experiment-statistics-card>
@@ -22,6 +23,7 @@
           :count="experimentStatistics.createdExperimentCount || 0"
           :states="createdStates"
           title="Created Experiments"
+          @click="selectExperiments(experimentStatistics.createdExperiments)"
         >
         </experiment-statistics-card>
       </div>
@@ -32,6 +34,7 @@
           :count="experimentStatistics.runningExperimentCount || 0"
           :states="runningStates"
           title="Running Experiments"
+          @click="selectExperiments(experimentStatistics.runningExperiments)"
         >
         </experiment-statistics-card>
 
@@ -44,6 +47,7 @@
           :count="experimentStatistics.completedExperimentCount || 0"
           :states="completedStates"
           title="Completed Experiments"
+          @click="selectExperiments(experimentStatistics.completedExperiments)"
         >
         </experiment-statistics-card>
       </div>
@@ -55,6 +59,7 @@
           :count="experimentStatistics.cancelledExperimentCount || 0"
           :states="canceledStates"
           title="Cancelled Experiments"
+          @click="selectExperiments(experimentStatistics.cancelledExperiments)"
         >
         </experiment-statistics-card>
       </div>
@@ -66,22 +71,61 @@
           :count="experimentStatistics.failedExperimentCount || 0"
           :states="failedStates"
           title="Failed Experiments"
+          @click="selectExperiments(experimentStatistics.failedExperiments)"
         >
         </experiment-statistics-card>
 
       </div>
     </div>
+    <div
+      class="row"
+      v-if="items.length"
+    >
+      <div class="col">
+        <b-table
+          :fields="fields"
+          :items="items"
+        >
+          <template
+            slot="executionId"
+            slot-scope="data"
+          >
+            <application-name :application-interface-id="data.value" />
+          </template>
+          <template
+            slot="resourceHostId"
+            slot-scope="data"
+          >
+            <compute-resource-name :compute-resource-id="data.value" />
+          </template>
+          <template
+            slot="creationTime"
+            slot-scope="data"
+          >
+            <human-date :date="data.value" />
+          </template>
+          <template
+            slot="experimentStatus"
+            slot-scope="data"
+          >
+            <experiment-status-badge :status-name="data.value.name" />
+          </template>
+        </b-table>
+      </div>
+    </div>
   </div>
 </template>
 <script>
 import { models, services } from "django-airavata-api";
+import { components } from "django-airavata-common-ui";
 import ExperimentStatisticsCard from "./ExperimentStatisticsCard";
 
 export default {
   name: "experiment-statistics-container",
   data() {
     return {
-      experimentStatistics: {}
+      experimentStatistics: {},
+      selectedExperimentSummaries: null
     };
   },
   created() {
@@ -90,7 +134,11 @@ export default {
     );
   },
   components: {
-    ExperimentStatisticsCard
+    ExperimentStatisticsCard,
+    "application-name": components.ApplicationName,
+    "compute-resource-name": components.ComputeResourceName,
+    "human-date": components.HumanDate,
+    "experiment-status-badge": components.ExperimentStatusBadge
   },
   computed: {
     createdStates() {
@@ -115,6 +163,50 @@ export default {
     },
     failedStates() {
       return [models.ExperimentState.FAILED];
+    },
+    fields() {
+      return [
+        {
+          key: "name",
+          label: "Name"
+        },
+        {
+          key: "userName",
+          label: "Owner"
+        },
+        {
+          key: "executionId",
+          label: "Application"
+        },
+        {
+          key: "resourceHostId",
+          label: "Resource"
+        },
+        {
+          key: "creationTime",
+          label: "Creation Time"
+        },
+        {
+          key: "experimentStatus",
+          label: "Status"
+        },
+        {
+          key: "actions",
+          label: "Actions"
+        }
+      ];
+    },
+    items() {
+      if (this.selectedExperimentSummaries) {
+        return this.selectedExperimentSummaries;
+      } else {
+        return [];
+      }
+    }
+  },
+  methods: {
+    selectExperiments(experiments) {
+      this.selectedExperimentSummaries = experiments;
     }
   }
 };
diff --git a/django_airavata/apps/api/views.py b/django_airavata/apps/api/views.py
index 3e20e17..6bd8a93 100644
--- a/django_airavata/apps/api/views.py
+++ b/django_airavata/apps/api/views.py
@@ -1451,7 +1451,7 @@ class ExperimentStatisticsView(APIView):
         # TODO: convert from ISO-8601 to posix timestamp
         from_time = request.GET.get(
             'fromTime',
-            (datetime.utcnow() - timedelta(days=1)).timestamp() * 1000)
+            (datetime.utcnow() - timedelta(days=7)).timestamp() * 1000)
         to_time = request.GET.get(
             'toTime',
             datetime.utcnow().timestamp() * 1000)
diff --git a/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/ExperimentStatusBadge.vue b/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/ExperimentStatusBadge.vue
deleted file mode 100644
index bea963c..0000000
--- a/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/ExperimentStatusBadge.vue
+++ /dev/null
@@ -1,33 +0,0 @@
-<template>
-    <b-badge :variant="badgeVariant">{{ statusName }}</b-badge>
-</template>
-
-<script>
-import { models } from 'django-airavata-api'
-
-export default {
-    name: 'experiment-status-badge',
-    props: {
-        statusName: {
-            type: String,
-            required: true
-        }
-    },
-    computed: {
-        experimentState: function() {
-            return models.ExperimentState.byName(this.statusName);
-        },
-        badgeVariant: function() {
-            if (this.experimentState.isProgressing) {
-                return "secondary";
-            } else if (this.experimentState === models.ExperimentState.COMPLETED) {
-                return "success";
-            } else if (this.experimentState === models.ExperimentState.FAILED) {
-                return "danger";
-            } else {
-                return "info";
-            }
-        }
-    }
-}
-</script>
diff --git a/django_airavata/apps/workspace/static/django_airavata_workspace/js/containers/ExperimentListContainer.vue b/django_airavata/apps/workspace/static/django_airavata_workspace/js/containers/ExperimentListContainer.vue
index 90170ee..9f1c678 100644
--- a/django_airavata/apps/workspace/static/django_airavata_workspace/js/containers/ExperimentListContainer.vue
+++ b/django_airavata/apps/workspace/static/django_airavata_workspace/js/containers/ExperimentListContainer.vue
@@ -86,8 +86,6 @@
 import { models, services } from "django-airavata-api";
 import { components as comps } from "django-airavata-common-ui";
 
-import ExperimentStatusBadge from "../components/experiment/ExperimentStatusBadge.vue";
-
 import moment from "moment";
 import urls from "../utils/urls";
 
@@ -102,7 +100,7 @@ export default {
   },
   components: {
     pager: comps.Pager,
-    "experiment-status-badge": ExperimentStatusBadge
+    "experiment-status-badge": comps.ExperimentStatusBadge
   },
   methods: {
     nextExperiments: function() {
diff --git a/django_airavata/apps/workspace/static/django_airavata_workspace/js/containers/RecentExperimentsContainer.vue b/django_airavata/apps/workspace/static/django_airavata_workspace/js/containers/RecentExperimentsContainer.vue
index 95a6fd9..d3a5850 100644
--- a/django_airavata/apps/workspace/static/django_airavata_workspace/js/containers/RecentExperimentsContainer.vue
+++ b/django_airavata/apps/workspace/static/django_airavata_workspace/js/containers/RecentExperimentsContainer.vue
@@ -20,7 +20,6 @@
 </template>
 
 <script>
-import ExperimentStatusBadge from "../components/experiment/ExperimentStatusBadge.vue";
 import urls from "../utils/urls";
 import { models, services } from "django-airavata-api";
 import { components } from "django-airavata-common-ui";
@@ -34,7 +33,7 @@ export default {
     sidebar: components.Sidebar,
     "sidebar-header": components.SidebarHeader,
     "sidebar-feed": components.SidebarFeed,
-    ExperimentStatusBadge
+    "experiment-status-badge": components.ExperimentStatusBadge
   },
   created() {
     this.pollExperiments();
diff --git a/django_airavata/static/common/js/components/ApplicationName.vue b/django_airavata/static/common/js/components/ApplicationName.vue
new file mode 100644
index 0000000..161adae
--- /dev/null
+++ b/django_airavata/static/common/js/components/ApplicationName.vue
@@ -0,0 +1,40 @@
+<template>
+  <span :class="{'font-italic': notAvailable}">{{ applicationName }}</span>
+</template>
+<script>
+import { services } from "django-airavata-api";
+export default {
+  name: "application-name",
+  props: {
+    applicationInterfaceId: {
+      type: String,
+      required: true
+    }
+  },
+  data() {
+    return {
+      applicationInterface: null,
+      notAvailable: false
+    };
+  },
+  created() {
+    services.ApplicationInterfaceService.retrieve(
+      { lookup: this.applicationInterfaceId },
+      { ignoreErrors: true, cache: true }
+    )
+      .then(appInterface => (this.applicationInterface = appInterface))
+      .catch(() => (this.notAvailable = true));
+  },
+  computed: {
+    applicationName() {
+      if (this.notAvailable) {
+        return "N/A";
+      } else {
+        return this.applicationInterface
+          ? this.applicationInterface.applicationName
+          : "";
+      }
+    }
+  }
+};
+</script>
diff --git a/django_airavata/static/common/js/components/ComputeResourceName.vue b/django_airavata/static/common/js/components/ComputeResourceName.vue
new file mode 100644
index 0000000..ddb89c7
--- /dev/null
+++ b/django_airavata/static/common/js/components/ComputeResourceName.vue
@@ -0,0 +1,38 @@
+<template>
+  <span :class="{'font-italic': notAvailable}">{{ name }}</span>
+</template>
+<script>
+import { services } from "django-airavata-api";
+export default {
+  name: "compute-resource-name",
+  props: {
+    computeResourceId: {
+      type: String,
+      required: true
+    }
+  },
+  data() {
+    return {
+      computeResource: null,
+      notAvailable: false
+    };
+  },
+  created() {
+    services.ComputeResourceService.retrieve(
+      { lookup: this.computeResourceId },
+      { ignoreErrors: true, cache: true }
+    )
+      .then(computeResource => (this.computeResource = computeResource))
+      .catch(() => (this.notAvailable = true));
+  },
+  computed: {
+    name() {
+      if (this.notAvailable) {
+        return "N/A";
+      } else {
+        return this.computeResource ? this.computeResource.hostName : "";
+      }
+    }
+  }
+};
+</script>
diff --git a/django_airavata/static/common/js/components/ExperimentStatusBadge.vue b/django_airavata/static/common/js/components/ExperimentStatusBadge.vue
new file mode 100644
index 0000000..54b7829
--- /dev/null
+++ b/django_airavata/static/common/js/components/ExperimentStatusBadge.vue
@@ -0,0 +1,38 @@
+<template>
+  <b-badge :variant="badgeVariant">{{ statusName }}</b-badge>
+</template>
+
+<script>
+import { models } from "django-airavata-api";
+
+export default {
+  name: "experiment-status-badge",
+  props: {
+    statusName: {
+      type: String,
+      required: true
+    }
+  },
+  computed: {
+    experimentState: function() {
+      return models.ExperimentState.byName(this.statusName);
+    },
+    badgeVariant: function() {
+      if (this.experimentState.isProgressing) {
+        return "secondary";
+      } else if (this.experimentState === models.ExperimentState.COMPLETED) {
+        return "success";
+      } else if (
+        this.experimentState === models.ExperimentState.CANCELING ||
+        this.experimentState === models.ExperimentState.CANCELED
+      ) {
+        return "warning";
+      } else if (this.experimentState === models.ExperimentState.FAILED) {
+        return "danger";
+      } else {
+        return "info";
+      }
+    }
+  }
+};
+</script>
diff --git a/django_airavata/static/common/js/index.js b/django_airavata/static/common/js/index.js
index 74c1d3e..e7eda5d 100644
--- a/django_airavata/static/common/js/index.js
+++ b/django_airavata/static/common/js/index.js
@@ -1,10 +1,13 @@
 import ApplicationCard from "./components/ApplicationCard.vue";
+import ApplicationName from "./components/ApplicationName";
 import AutocompleteTextInput from "./components/AutocompleteTextInput.vue";
 import ClipboardCopyButton from "./components/ClipboardCopyButton.vue";
 import ClipboardCopyLink from "./components/ClipboardCopyLink.vue";
+import ComputeResourceName from "./components/ComputeResourceName";
 import ConfirmationDialog from "./components/ConfirmationDialog.vue";
 import DeleteButton from "./components/DeleteButton.vue";
 import DeleteLink from "./components/DeleteLink.vue";
+import ExperimentStatusBadge from "./components/ExperimentStatusBadge";
 import HumanDate from "./components/HumanDate.vue";
 import MainLayout from "./components/MainLayout.vue";
 import Pager from "./components/Pager.vue";
@@ -31,12 +34,15 @@ import entry from "./entry";
 const components = {
   Pager,
   ApplicationCard,
+  ApplicationName,
   AutocompleteTextInput,
   ClipboardCopyButton,
   ClipboardCopyLink,
+  ComputeResourceName,
   ConfirmationDialog,
   DeleteButton,
   DeleteLink,
+  ExperimentStatusBadge,
   HumanDate,
   MainLayout,
   ShareButton,
@@ -74,12 +80,4 @@ export default {
   utils
 };
 
-export {
-  components,
-  entry,
-  errors,
-  layouts,
-  mixins,
-  notifications,
-  utils
-};
+export { components, entry, errors, layouts, mixins, notifications, utils };