Merge pull request #68 from dinukadesilva/AIRAVATA-3552

AIRAVATA-3552: Adding the error stack to the experiment view error panel
diff --git a/django_airavata/apps/admin/static/django_airavata_admin/src/components/admin/group_resource_preferences/ComputeResourceReservationEditor.vue b/django_airavata/apps/admin/static/django_airavata_admin/src/components/admin/group_resource_preferences/ComputeResourceReservationEditor.vue
index b08ee8e..c58227c 100644
--- a/django_airavata/apps/admin/static/django_airavata_admin/src/components/admin/group_resource_preferences/ComputeResourceReservationEditor.vue
+++ b/django_airavata/apps/admin/static/django_airavata_admin/src/components/admin/group_resource_preferences/ComputeResourceReservationEditor.vue
@@ -143,7 +143,7 @@
       return utils.getProperty(this.data.validate(), properties);
     },
     getValidationState: function (properties) {
-      return this.getValidationFeedback(properties) ? "invalid" : null;
+      return this.getValidationFeedback(properties) ? false : null;
     },
     valuesChanged() {
       const validationResults = this.data.validate();
diff --git a/django_airavata/apps/admin/static/django_airavata_admin/src/components/applications/ApplicationDeploymentEditor.vue b/django_airavata/apps/admin/static/django_airavata_admin/src/components/applications/ApplicationDeploymentEditor.vue
index c9d1dc0..ecb5eba 100644
--- a/django_airavata/apps/admin/static/django_airavata_admin/src/components/applications/ApplicationDeploymentEditor.vue
+++ b/django_airavata/apps/admin/static/django_airavata_admin/src/components/applications/ApplicationDeploymentEditor.vue
@@ -117,6 +117,9 @@
             :max="maxCPUCount"
             :disabled="defaultQueueAttributesDisabled"
           ></b-form-input>
+          <template #description v-if="cpuPerNode > 0">
+            There are {{ cpuPerNode }} cores per node.
+          </template>
         </b-form-group>
         <b-form-group
           label="Default Walltime (in minutes)"
@@ -229,6 +232,14 @@
         : null;
       return queue ? queue.maxRuntime : 0;
     },
+    cpuPerNode() {
+      const queue = this.computeResource
+        ? this.computeResource.batchQueues.find(
+            (q) => q.queueName === this.data.defaultQueueName
+          )
+        : null;
+      return queue ? queue.cpuPerNode : 0;
+    },
     defaultQueueAttributesDisabled() {
       return !this.data.defaultQueueName || this.readonly;
     },
diff --git a/django_airavata/apps/admin/static/django_airavata_admin/src/components/notices/NoticeEditor.vue b/django_airavata/apps/admin/static/django_airavata_admin/src/components/notices/NoticeEditor.vue
index c3e634f..4ee9362 100644
--- a/django_airavata/apps/admin/static/django_airavata_admin/src/components/notices/NoticeEditor.vue
+++ b/django_airavata/apps/admin/static/django_airavata_admin/src/components/notices/NoticeEditor.vue
@@ -202,7 +202,7 @@
       if (this.userBeginsInput == false) {
         return null;
       }
-      return this.getValidationFeedback(properties) ? "invalid" : "valid";
+      return this.getValidationFeedback(properties) ? false : true;
     },
     cancelNewNotice() {
       return this.$emit("cancelNewNotice");
diff --git a/django_airavata/apps/admin/static/django_airavata_admin/src/components/users/UserDetailsContainer.vue b/django_airavata/apps/admin/static/django_airavata_admin/src/components/users/UserDetailsContainer.vue
index bc27702..d735160 100644
--- a/django_airavata/apps/admin/static/django_airavata_admin/src/components/users/UserDetailsContainer.vue
+++ b/django_airavata/apps/admin/static/django_airavata_admin/src/components/users/UserDetailsContainer.vue
@@ -60,6 +60,7 @@
         they can complete their user profile.
       </b-alert>
       <change-username-panel
+        v-if="isUsernameInvalid"
         :username="iamUserProfile.userId"
         :email="iamUserProfile.email"
         :airavata-user-profile-exists="iamUserProfile.airavataUserProfileExists"
diff --git a/django_airavata/apps/auth/backends.py b/django_airavata/apps/auth/backends.py
index b6e6edf..3a59fb6 100644
--- a/django_airavata/apps/auth/backends.py
+++ b/django_airavata/apps/auth/backends.py
@@ -330,7 +330,7 @@
 
         # TODO: also check idp_userinfo.preferred_username if it exists
 
-        if not user_profile.username_initialized:
+        if not user_profile.username_initialized and not user_profile.is_username_valid:
             try:
                 utils.send_admin_alert_about_uninitialized_username(
                     request, user.username, user.email, user.first_name, user.last_name)
diff --git a/django_airavata/apps/auth/models.py b/django_airavata/apps/auth/models.py
index 65ee94e..54395e0 100644
--- a/django_airavata/apps/auth/models.py
+++ b/django_airavata/apps/auth/models.py
@@ -74,8 +74,7 @@
         if self.username_initialized:
             return True
 
-        # use forms.USERNAME_VALIDATOR with an exception when the username is
-        # equal to the email
+        # use forms.USERNAME_VALIDATOR
         try:
             forms.USERNAME_VALIDATOR(self.user.username)
             validates = True
diff --git a/django_airavata/apps/auth/utils.py b/django_airavata/apps/auth/utils.py
index 7c29731..d7ebda8 100644
--- a/django_airavata/apps/auth/utils.py
+++ b/django_airavata/apps/auth/utils.py
@@ -166,11 +166,12 @@
     <p>Email: {{email}}</p>
 
     <p>
-    This likely happened because there was no appropriate user attribute to use
-    for the user's username when the user logged in through an external identity
-    provider.  Please update the username to the user's email address or some
-    other appropriate value in the <a href="https://{{http_host}}/admin/users/">Manage
-    Users</a> view in the portal.
+    This likely happened because there was no appropriate user attribute
+    (typically email address) to use for the user's username when the user
+    logged in through an external identity provider.  Please update the username
+    to the user's email address or some other appropriate value in the <a
+    href="https://{{http_host}}/admin/users/">Manage Users</a> view in the
+    portal.
     </p>
     """.strip()).render(context)
     msg = EmailMessage(subject=subject,
diff --git a/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/ComputationalResourceSchedulingEditor.vue b/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/ComputationalResourceSchedulingEditor.vue
index cf5f313..45db176 100644
--- a/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/ComputationalResourceSchedulingEditor.vue
+++ b/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/ComputationalResourceSchedulingEditor.vue
@@ -243,7 +243,7 @@
       return utils.getProperty(this.validation, properties);
     },
     getValidationState: function (properties) {
-      return this.getValidationFeedback(properties) ? "invalid" : null;
+      return this.getValidationFeedback(properties) ? false : null;
     },
   },
   watch: {
diff --git a/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/ExperimentEditor.vue b/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/ExperimentEditor.vue
index 9ee78ef..acaa927 100644
--- a/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/ExperimentEditor.vue
+++ b/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/ExperimentEditor.vue
@@ -144,7 +144,7 @@
           <b-form-group
             label="Email Settings"
           >
-            <b-form-checkbox 
+            <b-form-checkbox
               v-model="localExperiment.enableEmailNotification"
             >
               Receive email notification of experiment status
@@ -308,7 +308,7 @@
       return utils.getProperty(this.localExperiment.validate(), properties);
     },
     getValidationState: function (properties) {
-      return this.getValidationFeedback(properties) ? "invalid" : null;
+      return this.getValidationFeedback(properties) ? false : null;
     },
     recordInvalidInputEditorValue: function (experimentInputName) {
       if (!this.invalidInputs.includes(experimentInputName)) {
diff --git a/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/QueueSettingsEditor.vue b/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/QueueSettingsEditor.vue
index 0a3ecbd..1a83ca0 100644
--- a/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/QueueSettingsEditor.vue
+++ b/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/QueueSettingsEditor.vue
@@ -102,8 +102,12 @@
             <div slot="description">
               <i class="fa fa-info-circle" aria-hidden="true"></i>
               Max Allowed Cores = {{ maxCPUCount
-              }}<template v-if="selectedQueueDefault && selectedQueueDefault.cpuPerNode > 0"
-                >. There are {{ selectedQueueDefault.cpuPerNode }} cores per node.
+              }}<template
+                v-if="
+                  selectedQueueDefault && selectedQueueDefault.cpuPerNode > 0
+                "
+                >. There are {{ selectedQueueDefault.cpuPerNode }} cores per
+                node.
               </template>
             </div>
           </b-form-group>
@@ -399,9 +403,9 @@
     },
     getValidationState: function (properties, showValidState) {
       return this.getValidationFeedback(properties)
-        ? "invalid"
+        ? false
         : showValidState
-        ? "valid"
+        ? true
         : null;
     },
     applyBatchQueueResourcePolicy() {
diff --git a/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/storage/storage-edit/UserStorageTextEditViewer.vue b/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/storage/storage-edit/UserStorageTextEditViewer.vue
index 49cd2c8..a78a528 100644
--- a/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/storage/storage-edit/UserStorageTextEditViewer.vue
+++ b/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/storage/storage-edit/UserStorageTextEditViewer.vue
@@ -104,15 +104,11 @@
     setFileContent() {
       this.loadDataProduct().then(() => {
         if (this.editAvailable) {
-          utils.FetchUtils.get(
-            this.downloadUrl,
-            "",
-            {
-              ignoreErrors: false,
-              showSpinner: true,
-            },
-            "text"
-          ).then((res) => {
+          utils.FetchUtils.get(this.downloadUrl, "", {
+            ignoreErrors: false,
+            showSpinner: true,
+            responseType: "text",
+          }).then((res) => {
             this.fileContent = res;
             this.setFileContentEditor(this.fileContent);
           });