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:19 UTC

[airavata-django-portal] 08/24: AIRAVATA-3477 Cleaning up after Vuex refactor

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 bdf764c95f283caa69b55641ea56c75469a0b96c
Author: Marcus Christie <ma...@apache.org>
AuthorDate: Wed Sep 1 13:36:20 2021 -0400

    AIRAVATA-3477 Cleaning up after Vuex refactor
---
 .../js/web-components/ComputeResourceSelector.vue  |   4 +-
 .../ExperimentComputeResourceSelector.vue          |   4 +-
 .../js/web-components/ExperimentEditor.vue         |   4 +-
 .../GroupResourceProfileSelector.vue               |   4 +-
 .../js/web-components/ProjectSelector.vue          |   4 +-
 .../js/web-components/QueueSettingsEditor.vue      |   4 +-
 .../js/web-components/ResourceSelectionEditor.vue  | 426 ------------
 .../input-editors/StringInputEditor.vue            |   4 +-
 .../js/web-components/store.js                     | 733 +++++++++++++++++----
 .../js/web-components/vuestore.js                  | 617 -----------------
 10 files changed, 625 insertions(+), 1179 deletions(-)

diff --git a/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/ComputeResourceSelector.vue b/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/ComputeResourceSelector.vue
index c438aa3..463d6f8 100644
--- a/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/ComputeResourceSelector.vue
+++ b/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/ComputeResourceSelector.vue
@@ -16,7 +16,7 @@
 </template>
 
 <script>
-import vuestore from "./vuestore";
+import store from "./store";
 import { mapGetters } from "vuex";
 
 export default {
@@ -32,7 +32,7 @@ export default {
       default: null,
     },
   },
-  store: vuestore,
+  store: store,
   data() {
     return {
       resourceHostId: this.value,
diff --git a/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/ExperimentComputeResourceSelector.vue b/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/ExperimentComputeResourceSelector.vue
index 715f63e..fe17520 100644
--- a/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/ExperimentComputeResourceSelector.vue
+++ b/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/ExperimentComputeResourceSelector.vue
@@ -7,13 +7,13 @@
 </template>
 
 <script>
-import vuestore from "./vuestore";
+import store from "./store";
 import { mapGetters } from "vuex";
 import ComputeResourceSelector from "./ComputeResourceSelector.vue";
 
 export default {
   name: "experiment-compute-resource-selector",
-  store: vuestore,
+  store: store,
   components: {
     ComputeResourceSelector,
   },
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 6bb75d0..339e02e 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
@@ -38,7 +38,7 @@
 
 <script>
 import Vue from "vue";
-import vuestore from "./vuestore";
+import store from "./store";
 import { mapGetters } from "vuex";
 import { BootstrapVue } from "bootstrap-vue";
 import urls from "../utils/urls";
@@ -56,7 +56,7 @@ export default {
       required: false,
     },
   },
-  store: vuestore,
+  store: store,
   async created() {},
   async mounted() {
     if (this.experimentId) {
diff --git a/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/GroupResourceProfileSelector.vue b/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/GroupResourceProfileSelector.vue
index 7be711f..2858629 100644
--- a/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/GroupResourceProfileSelector.vue
+++ b/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/GroupResourceProfileSelector.vue
@@ -19,7 +19,7 @@
 <script>
 import Vue from "vue";
 import { BootstrapVue } from "bootstrap-vue";
-import vuestore from "./vuestore";
+import store from "./store";
 import { mapGetters } from "vuex";
 Vue.use(BootstrapVue);
 
@@ -35,7 +35,7 @@ export default {
       default: "Allocation",
     },
   },
-  store: vuestore,
+  store: store,
   data() {
     return {
       groupResourceProfileId: this.value,
diff --git a/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/ProjectSelector.vue b/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/ProjectSelector.vue
index dc4bddf..797f4e3 100644
--- a/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/ProjectSelector.vue
+++ b/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/ProjectSelector.vue
@@ -28,7 +28,7 @@
 
 <script>
 import Vue from "vue";
-import vuestore from "./vuestore";
+import store from "./store";
 import { mapGetters } from "vuex";
 import { BootstrapVue } from "bootstrap-vue";
 Vue.use(BootstrapVue);
@@ -40,7 +40,7 @@ export default {
       default: null,
     },
   },
-  store: vuestore,
+  store: store,
   data() {
     return {
       projectId: this.value,
diff --git a/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/QueueSettingsEditor.vue b/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/QueueSettingsEditor.vue
index 5bb644a..09f8bd6 100644
--- a/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/QueueSettingsEditor.vue
+++ b/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/QueueSettingsEditor.vue
@@ -128,7 +128,7 @@
 <script>
 import { utils } from "django-airavata-api";
 import Vue from "vue";
-import vuestore from "./vuestore";
+import store from "./store";
 import { mapGetters } from "vuex";
 import { BootstrapVue } from "bootstrap-vue";
 Vue.use(BootstrapVue);
@@ -144,7 +144,7 @@ export default {
   components: {
     FontAwesomeIcon,
   },
-  store: vuestore,
+  store: store,
   mounted() {
     // Add font awesome styles
     // https://github.com/FortAwesome/vue-fontawesome#web-components-with-vue-web-component-wrapper
diff --git a/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/ResourceSelectionEditor.vue b/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/ResourceSelectionEditor.vue
deleted file mode 100644
index 9557db9..0000000
--- a/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/ResourceSelectionEditor.vue
+++ /dev/null
@@ -1,426 +0,0 @@
-<template>
-<!-- TODO: this is no longer needed -->
-  <div v-if="userConfigurationData">
-    <div @input.stop="updateGroupResourceProfileId">
-      <adpf-group-resource-profile-selector
-        slot="resource-selection-grp"
-        :value="userConfigurationData.groupResourceProfileId"
-      />
-    </div>
-    <div @input.stop="updateComputeResourceHostId">
-      <adpf-compute-resource-selector
-        ref="computeResourceSelector"
-        slot="resource-selection-compute-resource"
-        :value="
-          userConfigurationData.computationalResourceScheduling.resourceHostId
-        "
-      />
-    </div>
-    <div @input.stop="updateComputationalResourceScheduling">
-      <adpf-queue-settings-editor
-        ref="queueSettingsEditor"
-        slot="resource-selection-queue-settings"
-        :max-allowed-nodes="maxAllowedNodes"
-        :max-allowed-cores="maxAllowedCores"
-        :max-allowed-walltime="maxAllowedWalltime"
-        :max-memory="maxMemory"
-      />
-    </div>
-  </div>
-</template>
-
-<script>
-import { models } from "django-airavata-api";
-import {
-  getAppDeploymentQueues,
-  getApplicationDeployments,
-  getDefaultComputeResourceId,
-  getDefaultGroupResourceProfileId,
-  getGroupResourceProfile,
-} from "./store";
-export default {
-  // TODO: better name? UserConfigurationDataEditor?
-  name: "resource-selection-editor",
-  props: {
-    value: {
-      type: models.UserConfigurationData,
-    },
-    applicationModuleId: {
-      type: String,
-    },
-  },
-  data() {
-    return {
-      userConfigurationData: this.cloneValue(),
-      applicationDeployments: [],
-      appDeploymentQueues: [],
-      groupResourceProfile: null,
-    };
-  },
-  computed: {
-    computeResources() {
-      return this.applicationDeployments.map((dep) => dep.computeHostId);
-    },
-    groupResourceProfileId() {
-      return this.userConfigurationData
-        ? this.userConfigurationData.groupResourceProfileId
-        : null;
-    },
-    resourceHostId() {
-      return this.userConfigurationData &&
-        this.userConfigurationData.computationalResourceScheduling
-        ? this.userConfigurationData.computationalResourceScheduling
-            .resourceHostId
-        : null;
-    },
-    applicationDeployment() {
-      if (this.applicationDeployments && this.resourceHostId) {
-        return this.applicationDeployments.find(
-          (ad) => ad.computeHostId === this.resourceHostId
-        );
-      } else {
-        return null;
-      }
-    },
-    computeResourcePolicy() {
-      if (!this.groupResourceProfile || !this.resourceHostId) {
-        return null;
-      }
-      return this.groupResourceProfile.computeResourcePolicies.find(
-        (crp) => crp.computeResourceId === this.resourceHostId
-      );
-    },
-    batchQueueResourcePolicies: function () {
-      if (!this.groupResourceProfile || !this.resourceHostId) {
-        return null;
-      }
-      return this.groupResourceProfile.batchQueueResourcePolicies.filter(
-        (bqrp) => bqrp.computeResourceId === this.resourceHostId
-      );
-    },
-    batchQueueResourcePolicy() {
-      if (!this.batchQueueResourcePolicies || !this.queueName) {
-        return null;
-      }
-      return this.batchQueueResourcePolicies.find(
-        (bqrp) => bqrp.queuename === this.queueName
-      );
-    },
-    queueName() {
-      return this.userConfigurationData &&
-        this.userConfigurationData.computationalResourceScheduling
-        ? this.userConfigurationData.computationalResourceScheduling.queueName
-        : null;
-    },
-    queues() {
-      return this.appDeploymentQueues
-        ? this.appDeploymentQueues.filter((q) =>
-            this.isQueueInComputeResourcePolicy(q.queueName)
-          )
-        : [];
-    },
-    queue() {
-      return this.queues && this.queueName
-        ? this.queues.find((q) => q.queueName === this.queueName)
-        : null;
-    },
-    maxAllowedCores: function () {
-      if (!this.queue) {
-        return 0;
-      }
-      const batchQueueResourcePolicy = this.batchQueueResourcePolicy;
-      if (batchQueueResourcePolicy) {
-        return Math.min(
-          batchQueueResourcePolicy.maxAllowedCores,
-          this.queue.maxProcessors
-        );
-      }
-      return this.queue.maxProcessors;
-    },
-    maxAllowedNodes: function () {
-      if (!this.queue) {
-        return 0;
-      }
-      const batchQueueResourcePolicy = this.batchQueueResourcePolicy;
-      if (batchQueueResourcePolicy) {
-        return Math.min(
-          batchQueueResourcePolicy.maxAllowedNodes,
-          this.queue.maxNodes
-        );
-      }
-      return this.queue.maxNodes;
-    },
-    maxAllowedWalltime: function () {
-      if (!this.queue) {
-        return 0;
-      }
-      const batchQueueResourcePolicy = this.batchQueueResourcePolicy;
-      if (batchQueueResourcePolicy) {
-        return Math.min(
-          batchQueueResourcePolicy.maxAllowedWalltime,
-          this.queue.maxRunTime
-        );
-      }
-      return this.queue.maxRunTime;
-    },
-    maxMemory() {
-      return this.queue ? this.queue.maxMemory : 0;
-    },
-  },
-  methods: {
-    emitValueChanged: function () {
-      const inputEvent = new CustomEvent("input", {
-        detail: [this.userConfigurationData.clone()],
-        composed: true,
-        bubbles: true,
-      });
-      this.$el.dispatchEvent(inputEvent);
-    },
-    async updateGroupResourceProfileId(event) {
-      const [groupResourceProfileId] = event.detail;
-      this.userConfigurationData.groupResourceProfileId = groupResourceProfileId;
-      await this.loadGroupResourceProfile();
-      await this.loadApplicationDeployments();
-      await this.applyGroupResourceProfile();
-      this.emitValueChanged();
-    },
-    async updateComputeResourceHostId(event) {
-      const [computeResourceHostId] = event.detail;
-      if (
-        this.userConfigurationData.computationalResourceScheduling
-          .resourceHostId !== computeResourceHostId
-      ) {
-        this.userConfigurationData.computationalResourceScheduling.resourceHostId = computeResourceHostId;
-        await this.loadAppDeploymentQueues();
-        this.setDefaultQueue();
-        this.emitValueChanged();
-      }
-    },
-    updateComputationalResourceScheduling(event) {
-      const [computationalResourceScheduling] = event.detail;
-      const queueChanged =
-        this.queueName !== computationalResourceScheduling.queueName;
-      this.userConfigurationData.computationalResourceScheduling = computationalResourceScheduling;
-      if (queueChanged) {
-        this.initializeQueue();
-      }
-      this.emitValueChanged();
-    },
-    async loadApplicationDeployments() {
-      this.applicationDeployments = await getApplicationDeployments(
-        this.applicationModuleId,
-        this.groupResourceProfileId
-      );
-    },
-    async initializeGroupResourceProfileId() {
-      this.userConfigurationData.groupResourceProfileId = await getDefaultGroupResourceProfileId();
-    },
-    async applyGroupResourceProfile() {
-      // Make sure that resource host id is in the list of app deployments
-      const computeResourceChanged = await this.initializeResourceHostId();
-      if (computeResourceChanged) {
-        await this.loadAppDeploymentQueues();
-        this.setDefaultQueue();
-      } else if (!this.queue) {
-        // allowed queues may have changed. If selected queue isn't in the list
-        // of allowed queues, reset to the default
-        this.setDefaultQueue();
-      } else {
-        // reapply batchQueueResourcePolicy maximums since they may have changed
-        this.applyBatchQueueResourcePolicy();
-      }
-    },
-    async initializeResourceHostId() {
-      // if there isn't a selected compute resource or there is but it isn't in
-      // the list of app deployments, set a default one
-      // Returns true if the resourceHostId changed
-      if (
-        !this.resourceHostId ||
-        !this.computeResources.find((crid) => crid === this.resourceHostId)
-      ) {
-        this.userConfigurationData.computationalResourceScheduling.resourceHostId = await this.getDefaultResourceHostId();
-        return true;
-      }
-      return false;
-    },
-    async loadAppDeploymentQueues() {
-      const applicationDeployment = this.applicationDeployment;
-      if (applicationDeployment) {
-        this.appDeploymentQueues = await getAppDeploymentQueues(
-          applicationDeployment.appDeploymentId
-        );
-      } else {
-        this.appDeploymentQueues = [];
-      }
-    },
-    setDefaultQueue() {
-      // set to the default queue or the first one
-      const defaultQueue = this.getDefaultQueue();
-      if (defaultQueue) {
-        this.userConfigurationData.computationalResourceScheduling.queueName =
-          defaultQueue.queueName;
-      } else {
-        this.userConfigurationData.computationalResourceScheduling.queueName = null;
-      }
-      this.initializeQueue();
-    },
-    isQueueInComputeResourcePolicy: function (queueName) {
-      if (!this.computeResourcePolicy) {
-        return true;
-      }
-      return this.computeResourcePolicy.allowedBatchQueues.includes(queueName);
-    },
-    initializeQueue() {
-      const queue = this.queue;
-      if (queue) {
-        const crs = this.userConfigurationData.computationalResourceScheduling;
-        crs.queueName = queue.queueName;
-        crs.totalCPUCount = this.getDefaultCPUCount(queue);
-        crs.nodeCount = this.getDefaultNodeCount(queue);
-        crs.wallTimeLimit = this.getDefaultWalltime(queue);
-        crs.totalPhysicalMemory = 0;
-      } else {
-        const crs = this.userConfigurationData.computationalResourceScheduling;
-        crs.queueName = null;
-        crs.totalCPUCount = 0;
-        crs.nodeCount = 0;
-        crs.wallTimeLimit = 0;
-        crs.totalPhysicalMemory = 0;
-      }
-    },
-    getDefaultQueue() {
-      const defaultQueue = this.queues.find((q) => q.isDefaultQueue);
-      if (defaultQueue) {
-        return defaultQueue;
-      } else if (this.queues.length > 0) {
-        return this.queues[0];
-      } else {
-        return null;
-      }
-    },
-    getDefaultCPUCount(queue) {
-      const batchQueueResourcePolicy = this.batchQueueResourcePolicy;
-      if (batchQueueResourcePolicy) {
-        return Math.min(
-          batchQueueResourcePolicy.maxAllowedCores,
-          queue.defaultCPUCount
-        );
-      }
-      return queue.defaultCPUCount;
-    },
-    getDefaultNodeCount(queue) {
-      const batchQueueResourcePolicy = this.batchQueueResourcePolicy;
-      if (batchQueueResourcePolicy) {
-        return Math.min(
-          batchQueueResourcePolicy.maxAllowedNodes,
-          queue.defaultNodeCount
-        );
-      }
-      return queue.defaultNodeCount;
-    },
-    getDefaultWalltime(queue) {
-      const batchQueueResourcePolicy = this.batchQueueResourcePolicy;
-      if (batchQueueResourcePolicy) {
-        return Math.min(
-          batchQueueResourcePolicy.maxAllowedWalltime,
-          queue.defaultWalltime
-        );
-      }
-      return queue.defaultWalltime;
-    },
-    applyBatchQueueResourcePolicy() {
-      if (this.batchQueueResourcePolicy) {
-        const crs = this.userConfigurationData.computationalResourceScheduling;
-        crs.totalCPUCount = Math.min(
-          crs.totalCPUCount,
-          this.batchQueueResourcePolicy.maxAllowedCores
-        );
-        crs.nodeCount = Math.min(
-          crs.nodeCount,
-          this.batchQueueResourcePolicy.maxAllowedNodes
-        );
-        crs.wallTimeLimit = Math.min(
-          crs.wallTimeLimit,
-          this.batchQueueResourcePolicy.maxAllowedWalltime
-        );
-      }
-    },
-    cloneValue() {
-      return this.value ? this.value.clone() : null;
-    },
-    async loadData() {
-      if (this.groupResourceProfileId) {
-        let groupResourceProfile = await this.loadGroupResourceProfile();
-        // handle user no longer has access to GRP
-        if (!groupResourceProfile) {
-          await this.initializeGroupResourceProfileId();
-          groupResourceProfile = await this.loadGroupResourceProfile();
-        }
-        if (groupResourceProfile) {
-          await this.loadApplicationDeployments();
-          await this.loadAppDeploymentQueues();
-          await this.applyGroupResourceProfile();
-          // If existing values are no longer selectable, the userConfigurationData
-          // may have changed
-          this.emitValueChanged();
-        }
-      } else {
-        await this.initializeGroupResourceProfileId();
-        if (this.groupResourceProfileId) {
-          await this.loadGroupResourceProfile();
-          await this.loadApplicationDeployments();
-          await this.applyGroupResourceProfile();
-          this.emitValueChanged();
-        }
-      }
-    },
-    async loadGroupResourceProfile() {
-      this.groupResourceProfile = await getGroupResourceProfile(
-        this.groupResourceProfileId
-      );
-      return this.groupResourceProfile;
-    },
-    async getDefaultResourceHostId() {
-      const defaultComputeResourceId = await getDefaultComputeResourceId();
-      if (
-        defaultComputeResourceId &&
-        this.computeResources.find((crid) => crid === defaultComputeResourceId)
-      ) {
-        return defaultComputeResourceId;
-      } else if (this.computeResources.length > 0) {
-        // Just pick the first one
-        return this.computeResources[0];
-      } else {
-        return null;
-      }
-    },
-    bindWebComponentProps() {
-      this.$nextTick(() => {
-        this.$refs.computeResourceSelector.value = this.resourceHostId;
-        this.$refs.queueSettingsEditor.value = this.userConfigurationData.computationalResourceScheduling;
-        this.$refs.queueSettingsEditor.queues = this.queues;
-      });
-    },
-  },
-  watch: {
-    value() {
-      this.userConfigurationData = this.cloneValue();
-      this.loadData();
-    },
-    computeResources: "bindWebComponentProps",
-    resourceHostId: "bindWebComponentProps",
-    "userConfigurationData.computationalResourceScheduling":
-      "bindWebComponentProps",
-    queues: "bindWebComponentProps",
-  },
-};
-</script>
-
-<style>
-@import "./styles.css";
-
-:host {
-  display: block;
-  margin-bottom: 1rem;
-}
-</style>
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
index 8f8cfd4..bed4a8c 100644
--- 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
@@ -19,7 +19,7 @@ import Vue from "vue";
 import { BootstrapVue } from "bootstrap-vue";
 import AsyncComputed from "vue-async-computed";
 import { utils } from "django-airavata-common-ui";
-import vuestore from "../vuestore";
+import store from "../store";
 Vue.use(BootstrapVue);
 Vue.use(AsyncComputed);
 
@@ -32,7 +32,7 @@ export default {
   components: {
     StringInputEditor,
   },
-  store: vuestore,
+  store: store,
   mounted() {
     this.$nextTick(() => {
       // Stop wrapped input editor 'input' event from bubbling up so it doesn't
diff --git a/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/store.js b/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/store.js
index 1f54748..a2128f5 100644
--- a/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/store.js
+++ b/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/store.js
@@ -1,128 +1,617 @@
-// TODO: this is no longer needed
 import { errors, services, utils } from "django-airavata-api";
-const CACHE = {
-  APPLICATION_MODULES: {},
-  APPLICATION_INTERFACES: {},
-  WORKSPACE_PREFERENCES: null,
-};
-export async function getApplicationModule(applicationId) {
-  if (!(applicationId in CACHE.APPLICATION_MODULES)) {
-    const promise = services.ApplicationModuleService.retrieve({
-      lookup: applicationId,
-    });
-    CACHE.APPLICATION_MODULES[applicationId] = promise;
-  }
-  return await CACHE.APPLICATION_MODULES[applicationId];
-}
-
-export async function getApplicationInterfaceForModule(applicationId) {
-  if (!(applicationId in CACHE.APPLICATION_INTERFACES)) {
-    const promise = services.ApplicationModuleService.getApplicationInterface({
-      lookup: applicationId,
-    });
-    CACHE.APPLICATION_INTERFACES[applicationId] = promise;
-  }
-  return await CACHE.APPLICATION_INTERFACES[applicationId];
-}
-
-export async function saveExperiment(experiment) {
-  if (experiment.experimentId) {
-    await services.ExperimentService.update({
-      data: experiment,
-      lookup: experiment.experimentId,
-    });
-  } else {
-    return await services.ExperimentService.create({ data: experiment });
-  }
-}
-
-export async function launchExperiment(experimentId) {
-  return await services.ExperimentService.launch({
-    lookup: experimentId,
-  });
-}
-
-export async function getWorkspacePreferences() {
-  if (!CACHE.WORKSPACE_PREFERENCES) {
-    CACHE.WORKSPACE_PREFERENCES = services.WorkspacePreferencesService.get();
-  }
-  return await CACHE.WORKSPACE_PREFERENCES;
-}
-
-export async function getDefaultProjectId() {
-  const prefs = await getWorkspacePreferences();
-  return prefs.most_recent_project_id;
-}
-
-export async function getDefaultGroupResourceProfileId() {
-  const prefs = await getWorkspacePreferences();
-  return prefs.most_recent_group_resource_profile_id;
-}
-
-export async function getDefaultComputeResourceId() {
-  const prefs = await getWorkspacePreferences();
-  return prefs.most_recent_compute_resource_id;
-}
+import Vue from "vue";
+import Vuex from "vuex";
 
-export async function getExperiment(experimentId) {
-  return await services.ExperimentService.retrieve({ lookup: experimentId });
-}
+Vue.use(Vuex);
 
-export async function getProjects() {
-  return await services.ProjectService.listAll();
-}
-
-export async function getGroupResourceProfiles() {
-  return await services.GroupResourceProfileService.list();
-}
+const PROMISES = {
+  workspacePreferences: null,
+};
+export default new Vuex.Store({
+  strict: process.env.NODE_ENV !== "production",
+  state: {
+    experiment: null,
+    projects: null,
+    computeResourceNames: {},
+    applicationDeployments: [],
+    groupResourceProfiles: null,
+    applicationModuleId: null,
+    appDeploymentQueues: [],
+  },
+  mutations: {
+    setExperiment(state, { experiment }) {
+      state.experiment = experiment;
+    },
+    updateExperimentName(state, { name }) {
+      state.experiment.experimentName = name;
+    },
+    updateExperimentInputValue(state, { inputName, value }) {
+      const experimentInput = state.experiment.experimentInputs.find(
+        (i) => i.name === inputName
+      );
+      experimentInput.value = value;
+    },
+    updateProjectId(state, { projectId }) {
+      state.experiment.projectId = projectId;
+    },
+    updateGroupResourceProfileId(state, { groupResourceProfileId }) {
+      state.experiment.userConfigurationData.groupResourceProfileId = groupResourceProfileId;
+    },
+    updateResourceHostId(state, { resourceHostId }) {
+      state.experiment.userConfigurationData.computationalResourceScheduling.resourceHostId = resourceHostId;
+    },
+    updateQueueName(state, { queueName }) {
+      state.experiment.userConfigurationData.computationalResourceScheduling.queueName = queueName;
+    },
+    updateTotalCPUCount(state, { totalCPUCount }) {
+      state.experiment.userConfigurationData.computationalResourceScheduling.totalCPUCount = totalCPUCount;
+    },
+    updateNodeCount(state, { nodeCount }) {
+      state.experiment.userConfigurationData.computationalResourceScheduling.nodeCount = nodeCount;
+    },
+    updateWallTimeLimit(state, { wallTimeLimit }) {
+      state.experiment.userConfigurationData.computationalResourceScheduling.wallTimeLimit = wallTimeLimit;
+    },
+    updateTotalPhysicalMemory(state, { totalPhysicalMemory }) {
+      state.experiment.userConfigurationData.computationalResourceScheduling.totalPhysicalMemory = totalPhysicalMemory;
+    },
+    setProjects(state, { projects }) {
+      state.projects = projects;
+    },
+    setComputeResourceNames(state, { computeResourceNames }) {
+      state.computeResourceNames = computeResourceNames;
+    },
+    setGroupResourceProfiles(state, { groupResourceProfiles }) {
+      state.groupResourceProfiles = groupResourceProfiles;
+    },
+    setWorkspacePreferences(state, { workspacePreferences }) {
+      state.workspacePreferences = workspacePreferences;
+    },
+    setApplicationModuleId(state, { applicationModuleId }) {
+      state.applicationModuleId = applicationModuleId;
+    },
+    setApplicationDeployments(state, { applicationDeployments }) {
+      state.applicationDeployments = applicationDeployments;
+    },
+    setAppDeploymentQueues(state, { appDeploymentQueues }) {
+      state.appDeploymentQueues = appDeploymentQueues;
+    },
+  },
+  actions: {
+    async loadNewExperiment({ commit, dispatch }, { applicationId }) {
+      const applicationModule = await services.ApplicationModuleService.retrieve(
+        {
+          lookup: applicationId,
+        }
+      );
+      const appInterface = await services.ApplicationModuleService.getApplicationInterface(
+        {
+          lookup: applicationId,
+        }
+      );
+      const experiment = appInterface.createExperiment();
+      const currentDate = new Date().toLocaleString([], {
+        dateStyle: "medium",
+        timeStyle: "short",
+      });
+      experiment.experimentName = `${applicationModule.appModuleName} on ${currentDate}`;
+      commit("setApplicationModuleId", { applicationModuleId: applicationId });
+      await dispatch("setExperiment", { experiment });
+    },
+    async loadExperiment({ commit, dispatch }, { experimentId }) {
+      const experiment = await services.ExperimentService.retrieve({
+        lookup: experimentId,
+      });
+      const appInterface = await services.ApplicationInterfaceService.retrieve({
+        lookup: experiment.executionId,
+      });
+      commit("setApplicationModuleId", {
+        applicationModuleId: appInterface.applicationModuleId,
+      });
+      await dispatch("setExperiment", { experiment });
+    },
+    async setExperiment({ commit, dispatch }, { experiment }) {
+      commit("setExperiment", { experiment });
+      await dispatch("loadExperimentData");
+    },
+    async loadExperimentData({ commit, dispatch, getters, state }) {
+      await Promise.all([
+        dispatch("loadProjects"),
+        dispatch("loadWorkspacePreferences"),
+        dispatch("loadGroupResourceProfiles"),
+      ]);
 
-export async function getGroupResourceProfile(groupResourceProfileId) {
-  return await services.GroupResourceProfileService.retrieve(
-    {
-      lookup: groupResourceProfileId,
-    },
-    { ignoreErrors: true }
-  )
-    .catch((error) => {
-      // Ignore unauthorized errors, force user to pick a different GroupResourceProfile
-      if (!errors.ErrorUtils.isUnauthorizedError(error)) {
-        return Promise.reject(error);
+      if (!state.experiment.projectId) {
+        commit("updateProjectId", {
+          projectId: state.workspacePreferences.most_recent_project_id,
+        });
+      }
+      // If there is no groupResourceProfileId set on the experiment, or there
+      // is one set but it is no longer in the list of accessible
+      // groupResourceProfiles, set to the default one
+      let groupResourceProfileId =
+        state.experiment.userConfigurationData.groupResourceProfileId;
+      if (
+        !groupResourceProfileId ||
+        !getters.findGroupResourceProfile(groupResourceProfileId)
+      ) {
+        commit("updateGroupResourceProfileId", {
+          groupResourceProfileId:
+            state.workspacePreferences.most_recent_group_resource_profile_id,
+        });
+      }
+      groupResourceProfileId =
+        state.experiment.userConfigurationData.groupResourceProfileId;
+      // If experiment has a group resource profile and user has access to it,
+      // load additional necessary data and re-apply group resource profile
+      if (getters.findGroupResourceProfile(groupResourceProfileId)) {
+        await dispatch("loadApplicationDeployments");
+        await dispatch("loadAppDeploymentQueues");
+        await dispatch("applyGroupResourceProfile");
+      }
+    },
+    updateExperimentName({ commit }, { name }) {
+      commit("updateExperimentName", { name });
+    },
+    updateExperimentInputValue({ commit }, { inputName, value }) {
+      commit("updateExperimentInputValue", { inputName, value });
+    },
+    updateProjectId({ commit }, { projectId }) {
+      commit("updateProjectId", { projectId });
+    },
+    async updateGroupResourceProfileId(
+      { commit, dispatch },
+      { groupResourceProfileId }
+    ) {
+      commit("updateGroupResourceProfileId", { groupResourceProfileId });
+      await dispatch("loadApplicationDeployments");
+      await dispatch("applyGroupResourceProfile");
+    },
+    async updateComputeResourceHostId(
+      { commit, dispatch, getters },
+      { resourceHostId }
+    ) {
+      if (getters.resourceHostId !== resourceHostId) {
+        commit("updateResourceHostId", { resourceHostId });
+        await dispatch("loadAppDeploymentQueues");
+        await dispatch("setDefaultQueue");
+      }
+    },
+    updateQueueName({ commit, dispatch }, { queueName }) {
+      commit("updateQueueName", { queueName });
+      dispatch("initializeQueue");
+    },
+    updateTotalCPUCount({ commit }, { totalCPUCount }) {
+      commit("updateTotalCPUCount", { totalCPUCount });
+    },
+    updateNodeCount({ commit }, { nodeCount }) {
+      commit("updateNodeCount", { nodeCount });
+    },
+    updateWallTimeLimit({ commit }, { wallTimeLimit }) {
+      commit("updateWallTimeLimit", { wallTimeLimit });
+    },
+    updateTotalPhysicalMemory({ commit }, { totalPhysicalMemory }) {
+      commit("updateTotalPhysicalMemory", { totalPhysicalMemory });
+    },
+    async loadApplicationDeployments({ commit, getters, state }) {
+      const applicationDeployments = await services.ApplicationDeploymentService.list(
+        {
+          appModuleId: state.applicationModuleId,
+          groupResourceProfileId: getters.groupResourceProfileId,
+        },
+        { ignoreErrors: true }
+      )
+        .catch((error) => {
+          // Ignore unauthorized errors, force user to pick another GroupResourceProfile
+          if (!errors.ErrorUtils.isUnauthorizedError(error)) {
+            return Promise.reject(error);
+          } else {
+            return Promise.resolve([]);
+          }
+        })
+        // Report all other error types
+        .catch(utils.FetchUtils.reportError);
+      commit("setApplicationDeployments", { applicationDeployments });
+    },
+    async applyGroupResourceProfile({ dispatch, getters }) {
+      // Make sure that resource host id is in the list of app deployments
+      const computeResourceChanged = await dispatch("initializeResourceHostId");
+      if (computeResourceChanged) {
+        await dispatch("loadAppDeploymentQueues");
+        await dispatch("setDefaultQueue");
+      } else if (!getters.queue) {
+        // allowed queues may have changed. If selected queue isn't in the list
+        // of allowed queues, reset to the default
+        await dispatch("setDefaultQueue");
       } else {
-        return Promise.resolve(null);
+        // reapply batchQueueResourcePolicy maximums since they may have changed
+        dispatch("applyBatchQueueResourcePolicy");
       }
-    })
-    // Report all other error types
-    .catch(utils.FetchUtils.reportError);
-}
-
-export async function getApplicationDeployments(
-  applicationId,
-  groupResourceProfileId
-) {
-  return await services.ApplicationDeploymentService.list(
-    {
-      appModuleId: applicationId,
-      groupResourceProfileId: groupResourceProfileId,
-    },
-    { ignoreErrors: true }
-  )
-    .catch((error) => {
-      // Ignore unauthorized errors, force user to pick another GroupResourceProfile
-      if (!errors.ErrorUtils.isUnauthorizedError(error)) {
-        return Promise.reject(error);
-      }
-    })
-    // Report all other error types
-    .catch(utils.FetchUtils.reportError);
-}
-
-export async function getComputeResourceNames() {
-  // TODO: cache these
-  return await services.ComputeResourceService.names();
-}
-
-export async function getAppDeploymentQueues(appDeploymentId) {
-  return await services.ApplicationDeploymentService.getQueues({
-    lookup: appDeploymentId,
-  });
-}
+    },
+    async initializeResourceHostId({ commit, dispatch, getters }) {
+      // if there isn't a selected compute resource or there is but it isn't in
+      // the list of app deployments, set a default one
+      // Returns true if the resourceHostId changed
+      if (
+        !getters.resourceHostId ||
+        !getters.computeResources.find(
+          (crid) => crid === getters.resourceHostId
+        )
+      ) {
+        const defaultResourceHostId = await dispatch(
+          "getDefaultResourceHostId"
+        );
+        commit("updateResourceHostId", {
+          resourceHostId: defaultResourceHostId,
+        });
+        return true;
+      }
+      return false;
+    },
+    async getDefaultResourceHostId({ dispatch, getters }) {
+      await dispatch("loadDefaultComputeResourceId");
+      if (
+        getters.defaultComputeResourceId &&
+        getters.computeResources.find(
+          (crid) => crid === getters.defaultComputeResourceId
+        )
+      ) {
+        return getters.defaultComputeResourceId;
+      } else if (getters.computeResources.length > 0) {
+        // Just pick the first one
+        return getters.computeResources[0];
+      } else {
+        return null;
+      }
+    },
+    async loadDefaultComputeResourceId({ dispatch }) {
+      await dispatch("loadWorkspacePreferences");
+    },
+    async loadAppDeploymentQueues({ commit, getters }) {
+      const applicationDeployment = getters.applicationDeployment;
+      if (applicationDeployment) {
+        const appDeploymentQueues = await services.ApplicationDeploymentService.getQueues(
+          {
+            lookup: applicationDeployment.appDeploymentId,
+          }
+        );
+        commit("setAppDeploymentQueues", { appDeploymentQueues });
+      } else {
+        commit("setAppDeploymentQueues", { appDeploymentQueues: [] });
+      }
+    },
+    async setDefaultQueue({ commit, dispatch, getters }) {
+      // set to the default queue or the first one
+      const defaultQueue = getters.defaultQueue;
+      if (defaultQueue) {
+        commit("updateQueueName", { queueName: defaultQueue.queueName });
+      } else {
+        commit("updateQueueName", { queueName: null });
+      }
+      dispatch("initializeQueue");
+    },
+    initializeQueue({ commit, getters }) {
+      const queue = getters.queue;
+      if (queue) {
+        commit("updateTotalCPUCount", {
+          totalCPUCount: getters.getDefaultCPUCount(queue),
+        });
+        commit("updateNodeCount", {
+          nodeCount: getters.getDefaultNodeCount(queue),
+        });
+        commit("updateWallTimeLimit", {
+          wallTimeLimit: getters.getDefaultWalltime(queue),
+        });
+        commit("updateTotalPhysicalMemory", { totalPhysicalMemory: 0 });
+      } else {
+        commit("updateTotalCPUCount", { totalCPUCount: 0 });
+        commit("updateNodeCount", { nodeCount: 0 });
+        commit("updateWallTimeLimit", { wallTimeLimit: 0 });
+        commit("updateTotalPhysicalMemory", { totalPhysicalMemory: 0 });
+      }
+    },
+    applyBatchQueueResourcePolicy({ commit, getters }) {
+      if (getters.batchQueueResourcePolicy) {
+        const crs =
+          getters.experiment.userConfigurationData
+            .computationalResourceScheduling;
+        commit("updateTotalCPUCount", {
+          totalCPUCount: Math.min(
+            crs.totalCPUCount,
+            getters.batchQueueResourcePolicy.maxAllowedCores
+          ),
+        });
+        commit("updateNodeCount", {
+          nodeCount: Math.min(
+            crs.nodeCount,
+            getters.batchQueueResourcePolicy.maxAllowedNodes
+          ),
+        });
+        commit("updateWallTimeLimit", {
+          wallTimeLimit: Math.min(
+            crs.wallTimeLimit,
+            getters.batchQueueResourcePolicy.maxAllowedWalltime
+          ),
+        });
+      }
+    },
+    async saveExperiment({ commit, getters }) {
+      if (getters.experiment.experimentId) {
+        const experiment = await services.ExperimentService.update({
+          data: getters.experiment,
+          lookup: getters.experiment.experimentId,
+        });
+        commit("setExperiment", { experiment });
+      } else {
+        const experiment = await services.ExperimentService.create({
+          data: getters.experiment,
+        });
+        commit("setExperiment", { experiment });
+      }
+    },
+    async launchExperiment({ getters }) {
+      await services.ExperimentService.launch({
+        lookup: getters.experiment.experimentId,
+      });
+    },
+    async loadProjects({ commit }) {
+      if (!PROMISES.projects) {
+        PROMISES.projects = services.ProjectService.listAll();
+      }
+      const projects = await PROMISES.projects;
+      commit("setProjects", { projects });
+    },
+    async loadWorkspacePreferences({ commit }) {
+      if (!PROMISES.workspacePreferences) {
+        PROMISES.workspacePreferences = services.WorkspacePreferencesService.get();
+      }
+      const workspacePreferences = await PROMISES.workspacePreferences;
+      commit("setWorkspacePreferences", { workspacePreferences });
+    },
+    async loadDefaultProjectId({ dispatch }) {
+      await dispatch("loadWorkspacePreferences");
+    },
+    async loadComputeResourceNames({ commit }) {
+      const computeResourceNames = await services.ComputeResourceService.names();
+      commit("setComputeResourceNames", { computeResourceNames });
+    },
+    async loadDefaultGroupResourceProfileId({ dispatch }) {
+      await dispatch("loadWorkspacePreferences");
+    },
+    async loadGroupResourceProfiles({ commit }) {
+      if (!PROMISES.groupResourceProfiles) {
+        PROMISES.groupResourceProfiles = services.GroupResourceProfileService.list();
+      }
+      const groupResourceProfiles = await PROMISES.groupResourceProfiles;
+      commit("setGroupResourceProfiles", { groupResourceProfiles });
+    },
+  },
+  getters: {
+    getExperimentInputByName: (state) => (name) => {
+      if (!state.experiment) {
+        return null;
+      }
+      const experimentInputs = state.experiment.experimentInputs;
+      if (experimentInputs) {
+        for (const experimentInput of experimentInputs) {
+          if (experimentInput.name === name) {
+            return experimentInput;
+          }
+        }
+      }
+      return null;
+    },
+    experiment: (state) => state.experiment,
+    projects: (state) => state.projects,
+    defaultProjectId: (state) =>
+      state.workspacePreferences
+        ? state.workspacePreferences.most_recent_project_id
+        : null,
+    defaultGroupResourceProfileId: (state) =>
+      state.workspacePreferences
+        ? state.workspacePreferences.most_recent_group_resource_profile_id
+        : null,
+    defaultComputeResourceId: (state) =>
+      state.workspacePreferences
+        ? state.workspacePreferences.most_recent_compute_resource_id
+        : null,
+    computeResourceNames: (state) => state.computeResourceNames,
+    groupResourceProfiles: (state) => state.groupResourceProfiles,
+    groupResourceProfileId: (state) =>
+      state.experiment
+        ? state.experiment.userConfigurationData.groupResourceProfileId
+        : null,
+    findGroupResourceProfile: (state) => (groupResourceProfileId) =>
+      state.groupResourceProfiles
+        ? state.groupResourceProfiles.find(
+            (g) => g.groupResourceProfileId === groupResourceProfileId
+          )
+        : null,
+    groupResourceProfile: (state, getters) =>
+      getters.findGroupResourceProfile(getters.groupResourceProfileId),
+    resourceHostId: (state) =>
+      state.experiment &&
+      state.experiment.userConfigurationData &&
+      state.experiment.userConfigurationData.computationalResourceScheduling
+        ? state.experiment.userConfigurationData.computationalResourceScheduling
+            .resourceHostId
+        : null,
+    computeResources: (state) =>
+      state.applicationDeployments.map((dep) => dep.computeHostId),
+    applicationDeployment: (state, getters) => {
+      if (state.applicationDeployments && getters.resourceHostId) {
+        return state.applicationDeployments.find(
+          (ad) => ad.computeHostId === getters.resourceHostId
+        );
+      } else {
+        return null;
+      }
+    },
+    isQueueInComputeResourcePolicy: (state, getters) => (queueName) => {
+      if (!getters.computeResourcePolicy) {
+        return true;
+      }
+      return getters.computeResourcePolicy.allowedBatchQueues.includes(
+        queueName
+      );
+    },
+    queues: (state, getters) => {
+      return state.appDeploymentQueues
+        ? state.appDeploymentQueues.filter((q) =>
+            getters.isQueueInComputeResourcePolicy(q.queueName)
+          )
+        : [];
+    },
+    defaultQueue: (state, getters) => {
+      const defaultQueue = getters.queues.find((q) => q.isDefaultQueue);
+      if (defaultQueue) {
+        return defaultQueue;
+      } else if (getters.queues.length > 0) {
+        return getters.queues[0];
+      } else {
+        return null;
+      }
+    },
+    queueName: (state) => {
+      return state.experiment &&
+        state.experiment.userConfigurationData &&
+        state.experiment.userConfigurationData.computationalResourceScheduling
+        ? state.experiment.userConfigurationData.computationalResourceScheduling
+            .queueName
+        : null;
+    },
+    totalCPUCount: (state) => {
+      return state.experiment &&
+        state.experiment.userConfigurationData &&
+        state.experiment.userConfigurationData.computationalResourceScheduling
+        ? state.experiment.userConfigurationData.computationalResourceScheduling
+            .totalCPUCount
+        : null;
+    },
+    nodeCount: (state) => {
+      return state.experiment &&
+        state.experiment.userConfigurationData &&
+        state.experiment.userConfigurationData.computationalResourceScheduling
+        ? state.experiment.userConfigurationData.computationalResourceScheduling
+            .nodeCount
+        : null;
+    },
+    wallTimeLimit: (state) => {
+      return state.experiment &&
+        state.experiment.userConfigurationData &&
+        state.experiment.userConfigurationData.computationalResourceScheduling
+        ? state.experiment.userConfigurationData.computationalResourceScheduling
+            .wallTimeLimit
+        : null;
+    },
+    totalPhysicalMemory: (state) => {
+      return state.experiment &&
+        state.experiment.userConfigurationData &&
+        state.experiment.userConfigurationData.computationalResourceScheduling
+        ? state.experiment.userConfigurationData.computationalResourceScheduling
+            .totalPhysicalMemory
+        : null;
+    },
+    queue: (state, getters) => {
+      return getters.queues && getters.queueName
+        ? getters.queues.find((q) => q.queueName === getters.queueName)
+        : null;
+    },
+    getDefaultCPUCount: (state, getters) => (queue) => {
+      const batchQueueResourcePolicy = getters.batchQueueResourcePolicy;
+      if (batchQueueResourcePolicy) {
+        return Math.min(
+          batchQueueResourcePolicy.maxAllowedCores,
+          queue.defaultCPUCount
+        );
+      }
+      return queue.defaultCPUCount;
+    },
+    getDefaultNodeCount: (state, getters) => (queue) => {
+      const batchQueueResourcePolicy = getters.batchQueueResourcePolicy;
+      if (batchQueueResourcePolicy) {
+        return Math.min(
+          batchQueueResourcePolicy.maxAllowedNodes,
+          queue.defaultNodeCount
+        );
+      }
+      return queue.defaultNodeCount;
+    },
+    getDefaultWalltime: (state, getters) => (queue) => {
+      const batchQueueResourcePolicy = getters.batchQueueResourcePolicy;
+      if (batchQueueResourcePolicy) {
+        return Math.min(
+          batchQueueResourcePolicy.maxAllowedWalltime,
+          queue.defaultWalltime
+        );
+      }
+      return queue.defaultWalltime;
+    },
+    computeResourcePolicy: (state, getters) => {
+      if (!getters.groupResourceProfile || !getters.resourceHostId) {
+        return null;
+      }
+      return getters.groupResourceProfile.computeResourcePolicies.find(
+        (crp) => crp.computeResourceId === getters.resourceHostId
+      );
+    },
+    batchQueueResourcePolicies: (state, getters) => {
+      if (!getters.groupResourceProfile || !getters.resourceHostId) {
+        return null;
+      }
+      return getters.groupResourceProfile.batchQueueResourcePolicies.filter(
+        (bqrp) => bqrp.computeResourceId === getters.resourceHostId
+      );
+    },
+    batchQueueResourcePolicy: (state, getters) => {
+      if (!getters.batchQueueResourcePolicies || !getters.queueName) {
+        return null;
+      }
+      return getters.batchQueueResourcePolicies.find(
+        (bqrp) => bqrp.queuename === getters.queueName
+      );
+    },
+    maxAllowedCores: (state, getters) => {
+      if (!getters.queue) {
+        return 0;
+      }
+      const batchQueueResourcePolicy = getters.batchQueueResourcePolicy;
+      if (batchQueueResourcePolicy) {
+        return Math.min(
+          batchQueueResourcePolicy.maxAllowedCores,
+          getters.queue.maxProcessors
+        );
+      }
+      return getters.queue.maxProcessors;
+    },
+    maxAllowedNodes: (state, getters) => {
+      if (!getters.queue) {
+        return 0;
+      }
+      const batchQueueResourcePolicy = getters.batchQueueResourcePolicy;
+      if (batchQueueResourcePolicy) {
+        return Math.min(
+          batchQueueResourcePolicy.maxAllowedNodes,
+          getters.queue.maxNodes
+        );
+      }
+      return getters.queue.maxNodes;
+    },
+    maxAllowedWalltime: (state, getters) => {
+      if (!getters.queue) {
+        return 0;
+      }
+      const batchQueueResourcePolicy = getters.batchQueueResourcePolicy;
+      if (batchQueueResourcePolicy) {
+        return Math.min(
+          batchQueueResourcePolicy.maxAllowedWalltime,
+          getters.queue.maxRunTime
+        );
+      }
+      return getters.queue.maxRunTime;
+    },
+    maxMemory: (state, getters) => {
+      return getters.queue ? getters.queue.maxMemory : 0;
+    },
+  },
+});
diff --git a/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/vuestore.js b/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/vuestore.js
deleted file mode 100644
index a2128f5..0000000
--- a/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/vuestore.js
+++ /dev/null
@@ -1,617 +0,0 @@
-import { errors, services, utils } from "django-airavata-api";
-import Vue from "vue";
-import Vuex from "vuex";
-
-Vue.use(Vuex);
-
-const PROMISES = {
-  workspacePreferences: null,
-};
-export default new Vuex.Store({
-  strict: process.env.NODE_ENV !== "production",
-  state: {
-    experiment: null,
-    projects: null,
-    computeResourceNames: {},
-    applicationDeployments: [],
-    groupResourceProfiles: null,
-    applicationModuleId: null,
-    appDeploymentQueues: [],
-  },
-  mutations: {
-    setExperiment(state, { experiment }) {
-      state.experiment = experiment;
-    },
-    updateExperimentName(state, { name }) {
-      state.experiment.experimentName = name;
-    },
-    updateExperimentInputValue(state, { inputName, value }) {
-      const experimentInput = state.experiment.experimentInputs.find(
-        (i) => i.name === inputName
-      );
-      experimentInput.value = value;
-    },
-    updateProjectId(state, { projectId }) {
-      state.experiment.projectId = projectId;
-    },
-    updateGroupResourceProfileId(state, { groupResourceProfileId }) {
-      state.experiment.userConfigurationData.groupResourceProfileId = groupResourceProfileId;
-    },
-    updateResourceHostId(state, { resourceHostId }) {
-      state.experiment.userConfigurationData.computationalResourceScheduling.resourceHostId = resourceHostId;
-    },
-    updateQueueName(state, { queueName }) {
-      state.experiment.userConfigurationData.computationalResourceScheduling.queueName = queueName;
-    },
-    updateTotalCPUCount(state, { totalCPUCount }) {
-      state.experiment.userConfigurationData.computationalResourceScheduling.totalCPUCount = totalCPUCount;
-    },
-    updateNodeCount(state, { nodeCount }) {
-      state.experiment.userConfigurationData.computationalResourceScheduling.nodeCount = nodeCount;
-    },
-    updateWallTimeLimit(state, { wallTimeLimit }) {
-      state.experiment.userConfigurationData.computationalResourceScheduling.wallTimeLimit = wallTimeLimit;
-    },
-    updateTotalPhysicalMemory(state, { totalPhysicalMemory }) {
-      state.experiment.userConfigurationData.computationalResourceScheduling.totalPhysicalMemory = totalPhysicalMemory;
-    },
-    setProjects(state, { projects }) {
-      state.projects = projects;
-    },
-    setComputeResourceNames(state, { computeResourceNames }) {
-      state.computeResourceNames = computeResourceNames;
-    },
-    setGroupResourceProfiles(state, { groupResourceProfiles }) {
-      state.groupResourceProfiles = groupResourceProfiles;
-    },
-    setWorkspacePreferences(state, { workspacePreferences }) {
-      state.workspacePreferences = workspacePreferences;
-    },
-    setApplicationModuleId(state, { applicationModuleId }) {
-      state.applicationModuleId = applicationModuleId;
-    },
-    setApplicationDeployments(state, { applicationDeployments }) {
-      state.applicationDeployments = applicationDeployments;
-    },
-    setAppDeploymentQueues(state, { appDeploymentQueues }) {
-      state.appDeploymentQueues = appDeploymentQueues;
-    },
-  },
-  actions: {
-    async loadNewExperiment({ commit, dispatch }, { applicationId }) {
-      const applicationModule = await services.ApplicationModuleService.retrieve(
-        {
-          lookup: applicationId,
-        }
-      );
-      const appInterface = await services.ApplicationModuleService.getApplicationInterface(
-        {
-          lookup: applicationId,
-        }
-      );
-      const experiment = appInterface.createExperiment();
-      const currentDate = new Date().toLocaleString([], {
-        dateStyle: "medium",
-        timeStyle: "short",
-      });
-      experiment.experimentName = `${applicationModule.appModuleName} on ${currentDate}`;
-      commit("setApplicationModuleId", { applicationModuleId: applicationId });
-      await dispatch("setExperiment", { experiment });
-    },
-    async loadExperiment({ commit, dispatch }, { experimentId }) {
-      const experiment = await services.ExperimentService.retrieve({
-        lookup: experimentId,
-      });
-      const appInterface = await services.ApplicationInterfaceService.retrieve({
-        lookup: experiment.executionId,
-      });
-      commit("setApplicationModuleId", {
-        applicationModuleId: appInterface.applicationModuleId,
-      });
-      await dispatch("setExperiment", { experiment });
-    },
-    async setExperiment({ commit, dispatch }, { experiment }) {
-      commit("setExperiment", { experiment });
-      await dispatch("loadExperimentData");
-    },
-    async loadExperimentData({ commit, dispatch, getters, state }) {
-      await Promise.all([
-        dispatch("loadProjects"),
-        dispatch("loadWorkspacePreferences"),
-        dispatch("loadGroupResourceProfiles"),
-      ]);
-
-      if (!state.experiment.projectId) {
-        commit("updateProjectId", {
-          projectId: state.workspacePreferences.most_recent_project_id,
-        });
-      }
-      // If there is no groupResourceProfileId set on the experiment, or there
-      // is one set but it is no longer in the list of accessible
-      // groupResourceProfiles, set to the default one
-      let groupResourceProfileId =
-        state.experiment.userConfigurationData.groupResourceProfileId;
-      if (
-        !groupResourceProfileId ||
-        !getters.findGroupResourceProfile(groupResourceProfileId)
-      ) {
-        commit("updateGroupResourceProfileId", {
-          groupResourceProfileId:
-            state.workspacePreferences.most_recent_group_resource_profile_id,
-        });
-      }
-      groupResourceProfileId =
-        state.experiment.userConfigurationData.groupResourceProfileId;
-      // If experiment has a group resource profile and user has access to it,
-      // load additional necessary data and re-apply group resource profile
-      if (getters.findGroupResourceProfile(groupResourceProfileId)) {
-        await dispatch("loadApplicationDeployments");
-        await dispatch("loadAppDeploymentQueues");
-        await dispatch("applyGroupResourceProfile");
-      }
-    },
-    updateExperimentName({ commit }, { name }) {
-      commit("updateExperimentName", { name });
-    },
-    updateExperimentInputValue({ commit }, { inputName, value }) {
-      commit("updateExperimentInputValue", { inputName, value });
-    },
-    updateProjectId({ commit }, { projectId }) {
-      commit("updateProjectId", { projectId });
-    },
-    async updateGroupResourceProfileId(
-      { commit, dispatch },
-      { groupResourceProfileId }
-    ) {
-      commit("updateGroupResourceProfileId", { groupResourceProfileId });
-      await dispatch("loadApplicationDeployments");
-      await dispatch("applyGroupResourceProfile");
-    },
-    async updateComputeResourceHostId(
-      { commit, dispatch, getters },
-      { resourceHostId }
-    ) {
-      if (getters.resourceHostId !== resourceHostId) {
-        commit("updateResourceHostId", { resourceHostId });
-        await dispatch("loadAppDeploymentQueues");
-        await dispatch("setDefaultQueue");
-      }
-    },
-    updateQueueName({ commit, dispatch }, { queueName }) {
-      commit("updateQueueName", { queueName });
-      dispatch("initializeQueue");
-    },
-    updateTotalCPUCount({ commit }, { totalCPUCount }) {
-      commit("updateTotalCPUCount", { totalCPUCount });
-    },
-    updateNodeCount({ commit }, { nodeCount }) {
-      commit("updateNodeCount", { nodeCount });
-    },
-    updateWallTimeLimit({ commit }, { wallTimeLimit }) {
-      commit("updateWallTimeLimit", { wallTimeLimit });
-    },
-    updateTotalPhysicalMemory({ commit }, { totalPhysicalMemory }) {
-      commit("updateTotalPhysicalMemory", { totalPhysicalMemory });
-    },
-    async loadApplicationDeployments({ commit, getters, state }) {
-      const applicationDeployments = await services.ApplicationDeploymentService.list(
-        {
-          appModuleId: state.applicationModuleId,
-          groupResourceProfileId: getters.groupResourceProfileId,
-        },
-        { ignoreErrors: true }
-      )
-        .catch((error) => {
-          // Ignore unauthorized errors, force user to pick another GroupResourceProfile
-          if (!errors.ErrorUtils.isUnauthorizedError(error)) {
-            return Promise.reject(error);
-          } else {
-            return Promise.resolve([]);
-          }
-        })
-        // Report all other error types
-        .catch(utils.FetchUtils.reportError);
-      commit("setApplicationDeployments", { applicationDeployments });
-    },
-    async applyGroupResourceProfile({ dispatch, getters }) {
-      // Make sure that resource host id is in the list of app deployments
-      const computeResourceChanged = await dispatch("initializeResourceHostId");
-      if (computeResourceChanged) {
-        await dispatch("loadAppDeploymentQueues");
-        await dispatch("setDefaultQueue");
-      } else if (!getters.queue) {
-        // allowed queues may have changed. If selected queue isn't in the list
-        // of allowed queues, reset to the default
-        await dispatch("setDefaultQueue");
-      } else {
-        // reapply batchQueueResourcePolicy maximums since they may have changed
-        dispatch("applyBatchQueueResourcePolicy");
-      }
-    },
-    async initializeResourceHostId({ commit, dispatch, getters }) {
-      // if there isn't a selected compute resource or there is but it isn't in
-      // the list of app deployments, set a default one
-      // Returns true if the resourceHostId changed
-      if (
-        !getters.resourceHostId ||
-        !getters.computeResources.find(
-          (crid) => crid === getters.resourceHostId
-        )
-      ) {
-        const defaultResourceHostId = await dispatch(
-          "getDefaultResourceHostId"
-        );
-        commit("updateResourceHostId", {
-          resourceHostId: defaultResourceHostId,
-        });
-        return true;
-      }
-      return false;
-    },
-    async getDefaultResourceHostId({ dispatch, getters }) {
-      await dispatch("loadDefaultComputeResourceId");
-      if (
-        getters.defaultComputeResourceId &&
-        getters.computeResources.find(
-          (crid) => crid === getters.defaultComputeResourceId
-        )
-      ) {
-        return getters.defaultComputeResourceId;
-      } else if (getters.computeResources.length > 0) {
-        // Just pick the first one
-        return getters.computeResources[0];
-      } else {
-        return null;
-      }
-    },
-    async loadDefaultComputeResourceId({ dispatch }) {
-      await dispatch("loadWorkspacePreferences");
-    },
-    async loadAppDeploymentQueues({ commit, getters }) {
-      const applicationDeployment = getters.applicationDeployment;
-      if (applicationDeployment) {
-        const appDeploymentQueues = await services.ApplicationDeploymentService.getQueues(
-          {
-            lookup: applicationDeployment.appDeploymentId,
-          }
-        );
-        commit("setAppDeploymentQueues", { appDeploymentQueues });
-      } else {
-        commit("setAppDeploymentQueues", { appDeploymentQueues: [] });
-      }
-    },
-    async setDefaultQueue({ commit, dispatch, getters }) {
-      // set to the default queue or the first one
-      const defaultQueue = getters.defaultQueue;
-      if (defaultQueue) {
-        commit("updateQueueName", { queueName: defaultQueue.queueName });
-      } else {
-        commit("updateQueueName", { queueName: null });
-      }
-      dispatch("initializeQueue");
-    },
-    initializeQueue({ commit, getters }) {
-      const queue = getters.queue;
-      if (queue) {
-        commit("updateTotalCPUCount", {
-          totalCPUCount: getters.getDefaultCPUCount(queue),
-        });
-        commit("updateNodeCount", {
-          nodeCount: getters.getDefaultNodeCount(queue),
-        });
-        commit("updateWallTimeLimit", {
-          wallTimeLimit: getters.getDefaultWalltime(queue),
-        });
-        commit("updateTotalPhysicalMemory", { totalPhysicalMemory: 0 });
-      } else {
-        commit("updateTotalCPUCount", { totalCPUCount: 0 });
-        commit("updateNodeCount", { nodeCount: 0 });
-        commit("updateWallTimeLimit", { wallTimeLimit: 0 });
-        commit("updateTotalPhysicalMemory", { totalPhysicalMemory: 0 });
-      }
-    },
-    applyBatchQueueResourcePolicy({ commit, getters }) {
-      if (getters.batchQueueResourcePolicy) {
-        const crs =
-          getters.experiment.userConfigurationData
-            .computationalResourceScheduling;
-        commit("updateTotalCPUCount", {
-          totalCPUCount: Math.min(
-            crs.totalCPUCount,
-            getters.batchQueueResourcePolicy.maxAllowedCores
-          ),
-        });
-        commit("updateNodeCount", {
-          nodeCount: Math.min(
-            crs.nodeCount,
-            getters.batchQueueResourcePolicy.maxAllowedNodes
-          ),
-        });
-        commit("updateWallTimeLimit", {
-          wallTimeLimit: Math.min(
-            crs.wallTimeLimit,
-            getters.batchQueueResourcePolicy.maxAllowedWalltime
-          ),
-        });
-      }
-    },
-    async saveExperiment({ commit, getters }) {
-      if (getters.experiment.experimentId) {
-        const experiment = await services.ExperimentService.update({
-          data: getters.experiment,
-          lookup: getters.experiment.experimentId,
-        });
-        commit("setExperiment", { experiment });
-      } else {
-        const experiment = await services.ExperimentService.create({
-          data: getters.experiment,
-        });
-        commit("setExperiment", { experiment });
-      }
-    },
-    async launchExperiment({ getters }) {
-      await services.ExperimentService.launch({
-        lookup: getters.experiment.experimentId,
-      });
-    },
-    async loadProjects({ commit }) {
-      if (!PROMISES.projects) {
-        PROMISES.projects = services.ProjectService.listAll();
-      }
-      const projects = await PROMISES.projects;
-      commit("setProjects", { projects });
-    },
-    async loadWorkspacePreferences({ commit }) {
-      if (!PROMISES.workspacePreferences) {
-        PROMISES.workspacePreferences = services.WorkspacePreferencesService.get();
-      }
-      const workspacePreferences = await PROMISES.workspacePreferences;
-      commit("setWorkspacePreferences", { workspacePreferences });
-    },
-    async loadDefaultProjectId({ dispatch }) {
-      await dispatch("loadWorkspacePreferences");
-    },
-    async loadComputeResourceNames({ commit }) {
-      const computeResourceNames = await services.ComputeResourceService.names();
-      commit("setComputeResourceNames", { computeResourceNames });
-    },
-    async loadDefaultGroupResourceProfileId({ dispatch }) {
-      await dispatch("loadWorkspacePreferences");
-    },
-    async loadGroupResourceProfiles({ commit }) {
-      if (!PROMISES.groupResourceProfiles) {
-        PROMISES.groupResourceProfiles = services.GroupResourceProfileService.list();
-      }
-      const groupResourceProfiles = await PROMISES.groupResourceProfiles;
-      commit("setGroupResourceProfiles", { groupResourceProfiles });
-    },
-  },
-  getters: {
-    getExperimentInputByName: (state) => (name) => {
-      if (!state.experiment) {
-        return null;
-      }
-      const experimentInputs = state.experiment.experimentInputs;
-      if (experimentInputs) {
-        for (const experimentInput of experimentInputs) {
-          if (experimentInput.name === name) {
-            return experimentInput;
-          }
-        }
-      }
-      return null;
-    },
-    experiment: (state) => state.experiment,
-    projects: (state) => state.projects,
-    defaultProjectId: (state) =>
-      state.workspacePreferences
-        ? state.workspacePreferences.most_recent_project_id
-        : null,
-    defaultGroupResourceProfileId: (state) =>
-      state.workspacePreferences
-        ? state.workspacePreferences.most_recent_group_resource_profile_id
-        : null,
-    defaultComputeResourceId: (state) =>
-      state.workspacePreferences
-        ? state.workspacePreferences.most_recent_compute_resource_id
-        : null,
-    computeResourceNames: (state) => state.computeResourceNames,
-    groupResourceProfiles: (state) => state.groupResourceProfiles,
-    groupResourceProfileId: (state) =>
-      state.experiment
-        ? state.experiment.userConfigurationData.groupResourceProfileId
-        : null,
-    findGroupResourceProfile: (state) => (groupResourceProfileId) =>
-      state.groupResourceProfiles
-        ? state.groupResourceProfiles.find(
-            (g) => g.groupResourceProfileId === groupResourceProfileId
-          )
-        : null,
-    groupResourceProfile: (state, getters) =>
-      getters.findGroupResourceProfile(getters.groupResourceProfileId),
-    resourceHostId: (state) =>
-      state.experiment &&
-      state.experiment.userConfigurationData &&
-      state.experiment.userConfigurationData.computationalResourceScheduling
-        ? state.experiment.userConfigurationData.computationalResourceScheduling
-            .resourceHostId
-        : null,
-    computeResources: (state) =>
-      state.applicationDeployments.map((dep) => dep.computeHostId),
-    applicationDeployment: (state, getters) => {
-      if (state.applicationDeployments && getters.resourceHostId) {
-        return state.applicationDeployments.find(
-          (ad) => ad.computeHostId === getters.resourceHostId
-        );
-      } else {
-        return null;
-      }
-    },
-    isQueueInComputeResourcePolicy: (state, getters) => (queueName) => {
-      if (!getters.computeResourcePolicy) {
-        return true;
-      }
-      return getters.computeResourcePolicy.allowedBatchQueues.includes(
-        queueName
-      );
-    },
-    queues: (state, getters) => {
-      return state.appDeploymentQueues
-        ? state.appDeploymentQueues.filter((q) =>
-            getters.isQueueInComputeResourcePolicy(q.queueName)
-          )
-        : [];
-    },
-    defaultQueue: (state, getters) => {
-      const defaultQueue = getters.queues.find((q) => q.isDefaultQueue);
-      if (defaultQueue) {
-        return defaultQueue;
-      } else if (getters.queues.length > 0) {
-        return getters.queues[0];
-      } else {
-        return null;
-      }
-    },
-    queueName: (state) => {
-      return state.experiment &&
-        state.experiment.userConfigurationData &&
-        state.experiment.userConfigurationData.computationalResourceScheduling
-        ? state.experiment.userConfigurationData.computationalResourceScheduling
-            .queueName
-        : null;
-    },
-    totalCPUCount: (state) => {
-      return state.experiment &&
-        state.experiment.userConfigurationData &&
-        state.experiment.userConfigurationData.computationalResourceScheduling
-        ? state.experiment.userConfigurationData.computationalResourceScheduling
-            .totalCPUCount
-        : null;
-    },
-    nodeCount: (state) => {
-      return state.experiment &&
-        state.experiment.userConfigurationData &&
-        state.experiment.userConfigurationData.computationalResourceScheduling
-        ? state.experiment.userConfigurationData.computationalResourceScheduling
-            .nodeCount
-        : null;
-    },
-    wallTimeLimit: (state) => {
-      return state.experiment &&
-        state.experiment.userConfigurationData &&
-        state.experiment.userConfigurationData.computationalResourceScheduling
-        ? state.experiment.userConfigurationData.computationalResourceScheduling
-            .wallTimeLimit
-        : null;
-    },
-    totalPhysicalMemory: (state) => {
-      return state.experiment &&
-        state.experiment.userConfigurationData &&
-        state.experiment.userConfigurationData.computationalResourceScheduling
-        ? state.experiment.userConfigurationData.computationalResourceScheduling
-            .totalPhysicalMemory
-        : null;
-    },
-    queue: (state, getters) => {
-      return getters.queues && getters.queueName
-        ? getters.queues.find((q) => q.queueName === getters.queueName)
-        : null;
-    },
-    getDefaultCPUCount: (state, getters) => (queue) => {
-      const batchQueueResourcePolicy = getters.batchQueueResourcePolicy;
-      if (batchQueueResourcePolicy) {
-        return Math.min(
-          batchQueueResourcePolicy.maxAllowedCores,
-          queue.defaultCPUCount
-        );
-      }
-      return queue.defaultCPUCount;
-    },
-    getDefaultNodeCount: (state, getters) => (queue) => {
-      const batchQueueResourcePolicy = getters.batchQueueResourcePolicy;
-      if (batchQueueResourcePolicy) {
-        return Math.min(
-          batchQueueResourcePolicy.maxAllowedNodes,
-          queue.defaultNodeCount
-        );
-      }
-      return queue.defaultNodeCount;
-    },
-    getDefaultWalltime: (state, getters) => (queue) => {
-      const batchQueueResourcePolicy = getters.batchQueueResourcePolicy;
-      if (batchQueueResourcePolicy) {
-        return Math.min(
-          batchQueueResourcePolicy.maxAllowedWalltime,
-          queue.defaultWalltime
-        );
-      }
-      return queue.defaultWalltime;
-    },
-    computeResourcePolicy: (state, getters) => {
-      if (!getters.groupResourceProfile || !getters.resourceHostId) {
-        return null;
-      }
-      return getters.groupResourceProfile.computeResourcePolicies.find(
-        (crp) => crp.computeResourceId === getters.resourceHostId
-      );
-    },
-    batchQueueResourcePolicies: (state, getters) => {
-      if (!getters.groupResourceProfile || !getters.resourceHostId) {
-        return null;
-      }
-      return getters.groupResourceProfile.batchQueueResourcePolicies.filter(
-        (bqrp) => bqrp.computeResourceId === getters.resourceHostId
-      );
-    },
-    batchQueueResourcePolicy: (state, getters) => {
-      if (!getters.batchQueueResourcePolicies || !getters.queueName) {
-        return null;
-      }
-      return getters.batchQueueResourcePolicies.find(
-        (bqrp) => bqrp.queuename === getters.queueName
-      );
-    },
-    maxAllowedCores: (state, getters) => {
-      if (!getters.queue) {
-        return 0;
-      }
-      const batchQueueResourcePolicy = getters.batchQueueResourcePolicy;
-      if (batchQueueResourcePolicy) {
-        return Math.min(
-          batchQueueResourcePolicy.maxAllowedCores,
-          getters.queue.maxProcessors
-        );
-      }
-      return getters.queue.maxProcessors;
-    },
-    maxAllowedNodes: (state, getters) => {
-      if (!getters.queue) {
-        return 0;
-      }
-      const batchQueueResourcePolicy = getters.batchQueueResourcePolicy;
-      if (batchQueueResourcePolicy) {
-        return Math.min(
-          batchQueueResourcePolicy.maxAllowedNodes,
-          getters.queue.maxNodes
-        );
-      }
-      return getters.queue.maxNodes;
-    },
-    maxAllowedWalltime: (state, getters) => {
-      if (!getters.queue) {
-        return 0;
-      }
-      const batchQueueResourcePolicy = getters.batchQueueResourcePolicy;
-      if (batchQueueResourcePolicy) {
-        return Math.min(
-          batchQueueResourcePolicy.maxAllowedWalltime,
-          getters.queue.maxRunTime
-        );
-      }
-      return getters.queue.maxRunTime;
-    },
-    maxMemory: (state, getters) => {
-      return getters.queue ? getters.queue.maxMemory : 0;
-    },
-  },
-});