4951: Rearrange js to make use of Rails built-ins. Add generic AJAX error handler.
authorTom Clegg <tom@curoverse.com>
Thu, 12 Feb 2015 08:18:52 +0000 (03:18 -0500)
committerTom Clegg <tom@curoverse.com>
Thu, 12 Feb 2015 08:18:52 +0000 (03:18 -0500)
apps/workbench/app/assets/javascripts/ajax_error.js [new file with mode: 0644]
apps/workbench/app/assets/javascripts/request_shell_access.js
apps/workbench/app/controllers/users_controller.rb
apps/workbench/app/views/users/_manage_virtual_machines.html.erb
apps/workbench/app/views/users/request_shell_access.js [new file with mode: 0644]
apps/workbench/test/integration/user_manage_account_test.rb

diff --git a/apps/workbench/app/assets/javascripts/ajax_error.js b/apps/workbench/app/assets/javascripts/ajax_error.js
new file mode 100644 (file)
index 0000000..9012844
--- /dev/null
@@ -0,0 +1,15 @@
+$(document).on('ajax:error', function(e, xhr, status, error) {
+    var errorMessage = '' + status + ': ' + error;
+    // $btn is the element (button/link) that initiated the failed request.
+    var $btn = $(e.target);
+    // Populate some elements with the error text (e.g., a <p> in an alert div)
+    $($btn.attr('data-on-error-write')).text(errorMessage);
+    // Show some elements (e.g., an alert div)
+    $($btn.attr('data-on-error-show')).show();
+    // Hide some elements (e.g., a success/normal div)
+    $($btn.attr('data-on-error-hide')).hide();
+}).on('ajax:success', function(e) {
+    var $btn = $(e.target);
+    $($btn.attr('data-on-success-show')).show();
+    $($btn.attr('data-on-success-hide')).hide();
+});
index a40334b8a23f8d224a91edb9adf9bf3a69dbf985..792ab3131267c471766399353fd370e1a00cb682 100644 (file)
@@ -1,36 +1,10 @@
-$(document).ready(function(){
+$(document).on('ready ajax:success storage', function() {
+    // Update the "shell access requested" info box according to the
+    // current state of localStorage.
+    var msg = localStorage.getItem('request_shell_access');
     var $noShellAccessDiv = $('#no_shell_access');
-    if ($noShellAccessDiv.length) {
-      requestSent = localStorage.getItem('request_shell_access');
-      if (requestSent != null) {
-        $("#shell_access_requested_msg").html(requestSent)
-      } else {
-        $('div').remove('.shell_access_requested');
-      }
+    if ($noShellAccessDiv.length > 0) {
+        $('.alert-success p', $noShellAccessDiv).text(msg);
+        $('.alert-success', $noShellAccessDiv).toggle(!!msg);
     }
-  });
-
-$(document).
-  on('click', "#request_shell_submit", function(e){
-    $(this).html('Sending request ...');
-    $(this).prop('disabled', true);
-    $('div').remove('.request_shell_access_failed');
-
-    $.ajax('/').
-      success(function(data, status, jqxhr) {
-        $('div').remove('.no_shell_access_msg');
-        $('div').remove('.shell_access_requested');
-
-        $('.no_shell_access').append('<div class="alert alert-success"><p class="contain-align-left">A request for shell access was sent.</p></div>');
-        var timestamp = new Date();
-        localStorage.setItem("request_shell_access", "A request for shell access was sent on " +
-                                                      timestamp.toLocaleDateString() +
-                                                      " at " + timestamp.toLocaleTimeString());
-      }).
-      fail(function(jqxhr, status, error) {
-        var $sendButton = $('#request_shell_submit');
-        $sendButton.html('Request shell access');
-        $sendButton.prop('disabled', false);
-        $('.no_shell_access').append('<div class="request_shell_access_failed alert alert-danger"><p class="contain-align-left">Something went wrong. Please try again.</p></div>');
-      });
-  });
+});
index 6d9d8cb7d193f80300601b1bb1e42d516041387a..7dcd4cc08d3ea91802fbec54f424c44d3e8c5966 100644 (file)
@@ -305,10 +305,7 @@ class UsersController < ApplicationController
   def request_shell_access
     logger.warn "request_access: #{params.inspect}"
     params['request_url'] = request.url
-    respond_to do |format|
-      RequestShellAccessReporter.send_request(current_user, params).deliver
-      format.js {render nothing: true}
-    end
+    RequestShellAccessReporter.send_request(current_user, params).deliver
   end
 
   protected
index df5c71a18fc74849d31380575ef2def01706b420..43f2b7787c6f8e83bbf66bbd029bbd4e55fa5412 100644 (file)
@@ -2,26 +2,46 @@
   <p>
     For more information see <%= link_to raw('Arvados Docs &rarr; User Guide &rarr; SSH access'),
   "#{Rails.configuration.arvados_docsite}/user/getting_started/ssh-access-unix.html",
-  target: "_blank"%>.  A sample <i>~/.ssh/config</i> entry is provided below.
+  target: "_blank"%>.
+    <% if @my_virtual_machines.any? or true %>
+      A sample <code>~/.ssh/config</code> entry is provided below.
+    <% end %>
   </p>
 
   <% if !@my_virtual_machines.any? %>
-    <div id='no_shell_access' class='no_shell_access'>
-      <div class='no_shell_access_msg'>
-        You do not have access to any virtual machines.
-        Some Arvados features require using the command line.
-        You may request access to a hosted virtual machine with the command line shell.
-        &nbsp;&nbsp;&nbsp;
-        <div style='display:inline-block'>
-          <%= link_to({action: 'request_shell_access', controller: 'users', id: current_user.uuid},
-                       method: :post, remote: true, class: 'btn btn-xs btn-primary',
-                       id: 'request_shell_submit', data: {disable_with: "Sending request..."}) do %>
-              Send request for shell access
+    <div id="no_shell_access" class="no_shell_access">
+      <div class="alert alert-warning clearfix">
+        <p>
+          You do not have access to any virtual machines.  Some
+          Arvados features require using the command line.  You may
+          request access to a hosted virtual machine with the command
+          line shell.
+        </p>
+        <div class="pull-right">
+          <%= link_to({
+              action: 'request_shell_access',
+              controller: 'users',
+              id: current_user.uuid
+              },
+              method: :post,
+              remote: true,
+              class: 'btn btn-xs btn-primary',
+              data: {
+              disable_with: "Sending request...",
+              on_error_hide: '.no_shell_access .alert-success',
+              on_error_show: '.no_shell_access .alert-danger',
+              on_error_write: '.no_shell_access .alert-danger .error-text',
+              on_success_hide: '.no_shell_access .alert-danger',
+              }) do %>
+            Send request for shell access
           <% end %>
         </div>
-      </div><br/>
-      <div class='shell_access_requested alert alert-info'>
-        <p id='shell_access_requested_msg' class="contain-align-left">A request for shell access was sent eariler.</p>
+      </div>
+      <div class="alert alert-success" style="display:none">
+        <p class="contain-align-left"><%# (see javascripts/request_shell_access.js) %></p>
+      </div>
+      <div class="alert alert-danger" style="display:none">
+        <p class="contain-align-left">Sorry, something went wrong. Please try again. (<span class="error-text"></span>)</p>
       </div>
     </div>
   <% else %>
diff --git a/apps/workbench/app/views/users/request_shell_access.js b/apps/workbench/app/views/users/request_shell_access.js
new file mode 100644 (file)
index 0000000..b97e14d
--- /dev/null
@@ -0,0 +1,10 @@
+var timestamp = new Date();
+localStorage.setItem("request_shell_access",
+                     "A request for shell access was sent on " +
+                     timestamp.toLocaleDateString() +
+                     " at " +
+                     timestamp.toLocaleTimeString());
+// The storage event gets triggered automatically in _other_ windows
+// when we hit localStorage, but we also need to fire it manually in
+// _this_ window.
+$(document).trigger('storage');
index f2686e24708e32296acbd99e2eb49e3a6bd640fc..d0ddb499a62a8d22c0f24dee40c53d52dcd978d1 100644 (file)
@@ -138,24 +138,28 @@ class UserManageAccountTest < ActionDispatch::IntegrationTest
     visit page_with_token('spectator', '/manage_account')
     assert_text 'You do not have access to any virtual machines'
     click_link 'Send request for shell access'
-    assert_text 'A request for shell access was sent.'
-    assert_no_text 'You do not have access to any virtual machines.'
-    assert_no_selector 'a', text: 'Send request for shell access'
+
+    # Button text changes to "sending...", then back to normal. In the
+    # test suite we can't depend on confirming the "sending..." state
+    # before it goes back to normal, though.
+    ## assert_selector 'a', text: 'Sending request...'
+    assert_selector 'a', text: 'Send request for shell access'
+    assert_text 'A request for shell access was sent'
 
     # verify that the email was sent
     user = api_fixture('users')['spectator']
-    found_email = false
+    full_name = "#{user['first_name']} #{user['last_name']}"
+    expected = "Shell account request from #{full_name} (#{user['email']}, #{user['uuid']})"
+    found_email = 0
     ActionMailer::Base.deliveries.andand.each do |email|
-      full_name = (user['first_name'] || "") + " " + (user['last_name'] || "")
-      expected = "Shell account request from #{full_name} (#{user['email']}, #{user['uuid']})"
       if email.subject.include?(expected)
-        found_email = true
-        break
+        found_email += 1
       end
     end
-    assert_equal true, found_email, "Expected email after requesting shell access"
+    assert_equal 1, found_email, "Expected email after requesting shell access"
 
-    # revisit the page and verify the request sent message along with the request button.
+    # Revisit the page and verify the request sent message along with
+    # the request button.
     within('.navbar-fixed-top') do
       find('a', text: 'spectator').click
       within('.dropdown-menu') do