Arvados-DCO-1.1-Signed-off-by: Radhika Chippada <radhika@curoverse.com>
authorradhika <radhika@curoverse.com>
Fri, 30 Jun 2017 17:25:31 +0000 (13:25 -0400)
committerradhika <radhika@curoverse.com>
Fri, 30 Jun 2017 17:25:31 +0000 (13:25 -0400)
Merge branch 'master' into 11870-repositories-index

Conflicts:
apps/workbench/app/views/repositories/_show_help.html.erb
apps/workbench/app/views/users/_repositories.html.erb
apps/workbench/app/views/users/repositories.html.erb

13 files changed:
apps/workbench/app/controllers/repositories_controller.rb
apps/workbench/app/controllers/users_controller.rb
apps/workbench/app/views/layouts/body.html.erb
apps/workbench/app/views/repositories/_add_repository_modal.html.erb [moved from apps/workbench/app/views/users/_add_repository_modal.html.erb with 100% similarity]
apps/workbench/app/views/repositories/_show_help.html.erb
apps/workbench/app/views/repositories/_show_repositories.html.erb [new file with mode: 0644]
apps/workbench/app/views/repositories/_show_repositories_rows.html.erb [new file with mode: 0644]
apps/workbench/app/views/users/_repositories.html.erb [deleted file]
apps/workbench/app/views/users/repositories.html.erb [deleted file]
apps/workbench/test/controllers/repositories_controller_test.rb
apps/workbench/test/controllers/users_controller_test.rb
apps/workbench/test/integration/application_layout_test.rb
apps/workbench/test/integration/user_settings_menu_test.rb

index 2a39a9401857d6fe8035091d2af0100fca480b80..5ca6f22b02f54bf2ea3b213b7106717cd10c845b 100644 (file)
@@ -6,7 +6,7 @@ class RepositoriesController < ApplicationController
   before_filter :set_share_links, if: -> { defined? @object }
 
   def index_pane_list
-    %w(recent help)
+    %w(repositories help)
   end
 
   def show_pane_list
@@ -36,4 +36,72 @@ class RepositoriesController < ApplicationController
   def show_commit
     @commit = params[:commit]
   end
+
+  def all_repos
+    limit = params[:limit].andand.to_i || 100
+    offset = params[:offset].andand.to_i || 0
+    @filters = params[:filters] || []
+
+    if @filters.any?
+      owner_filter = @filters.select do |attr, op, val|
+        (attr == 'owner_uuid')
+      end
+    end
+
+    if !owner_filter.andand.any?
+      filters = @filters + [["owner_uuid", "=", current_user.uuid]]
+      my_repos = Repository.all.order("name ASC").limit(limit).offset(offset).filter(filters).results
+    else      # done fetching all owned repositories
+      my_repos = []
+    end
+
+    if !owner_filter.andand.any?  # if this is next page request, the first page was still fetching "own" repos
+      @filters = @filters.reject do |attr, op, val|
+        (attr == 'owner_uuid') or
+        (attr == 'name') or
+        (attr == 'uuid')
+      end
+    end
+
+    filters = @filters + [["owner_uuid", "!=", current_user.uuid]]
+    other_repos = Repository.all.order("name ASC").limit(limit).offset(offset).filter(filters).results
+
+    @objects = (my_repos + other_repos).first(limit)
+  end
+
+  def find_objects_for_index
+    return if !params[:partial]
+
+    all_repos
+
+    if @objects.any?
+      @next_page_filters = next_page_filters('>=')
+      @next_page_href = url_for(partial: :repositories_rows,
+                                filters: @next_page_filters.to_json)
+    else
+      @next_page_href = nil
+    end
+  end
+
+  def next_page_href with_params={}
+    @next_page_href
+  end
+
+  def next_page_filters nextpage_operator
+    next_page_filters = @filters.reject do |attr, op, val|
+      (attr == 'owner_uuid') or
+      (attr == 'name' and op == nextpage_operator) or
+      (attr == 'uuid' and op == 'not in')
+    end
+
+    if @objects.any?
+      last_obj = @objects.last
+      next_page_filters += [['name', nextpage_operator, last_obj.name]]
+      next_page_filters += [['uuid', 'not in', [last_obj.uuid]]]
+      # if not-owned, it means we are done with owned repos and fetching other repos
+      next_page_filters += [['owner_uuid', '!=', last_obj.uuid]] if last_obj.owner_uuid != current_user.uuid
+    end
+
+    next_page_filters
+  end
 end
index 4a40f031203f7a1663d5d92f1617511cf8906f3a..2e3ced69a534485ca5d18df22b19ac53abeea793 100644 (file)
@@ -260,28 +260,6 @@ class UsersController < ApplicationController
     end
   end
 
-  def repositories
-    # all repositories accessible by current user
-    all_repositories = Hash[Repository.all.order('name asc').collect {|repo| [repo.uuid, repo]}]
-
-    @my_repositories = [] # we want them ordered as owned and the rest
-    @repo_writable = {}
-
-    # owned repos
-    all_repositories.each do |_, repo|
-      if repo.owner_uuid == current_user.uuid
-        @repo_writable[repo.uuid] = 'can_write'
-        @my_repositories << repo
-      end
-    end
-
-    # rest of the repos
-    handled = @my_repositories.map(&:uuid)
-    all_repositories.each do |_, repo|
-      @my_repositories << repo if !repo.uuid.in?(handled)
-    end
-  end
-
   def virtual_machines
     @my_vm_logins = {}
     Link.where(tail_uuid: @object.uuid,
index 8073615c31cea407ecfcdd91fffc4fe9274bee91..3315027b3d9a1b485eaf0b578b86af1e1e68cb30 100644 (file)
@@ -66,11 +66,7 @@ SPDX-License-Identifier: AGPL-3.0 %>
                     <i class="fa fa-lg fa-terminal fa-fw"></i> Virtual machines
                   <% end %>
                 </li>
-                <li role="menuitem">
-                  <%= link_to repositories_user_path(current_user), role: 'menu-item' do %>
-                    <i class="fa fa-lg fa-code-fork fa-fw"></i> Repositories
-                  <% end %>
-                </li>
+                <li role="menuitem"><a href="/repositories" role="menuitem"><i class="fa fa-lg fa-code-fork fa-fw"></i> Repositories </a></li>
                 <li role="menuitem"><a href="/current_token" role="menuitem"><i class="fa fa-lg fa-ticket fa-fw"></i> Current token</a></li>
                 <li role="menuitem">
                   <%= link_to ssh_keys_user_path(current_user), role: 'menu-item' do %>
index 7980738b557d09abaf7f7f24caf553014f3bd845..5904fb29db8a513d05f0d9532cf666b650c1bb49 100644 (file)
@@ -2,7 +2,13 @@
 
 SPDX-License-Identifier: AGPL-3.0 %>
 
-<% if (example = @objects.select(&:push_url).first) %>
+<%
+    filters = @filters + [["owner_uuid", "=", current_user.uuid]]
+    example = Repository.all.order("name ASC").filter(filters).limit(1).results.first
+    example = Repository.all.order("name ASC").limit(1).results.first if !example
+%>
+
+<% if example %>
 
 <p>
 Sample git quick start:
diff --git a/apps/workbench/app/views/repositories/_show_repositories.html.erb b/apps/workbench/app/views/repositories/_show_repositories.html.erb
new file mode 100644 (file)
index 0000000..1a74eab
--- /dev/null
@@ -0,0 +1,42 @@
+<%= render partial: "add_repository_modal" %>
+
+<div class="container" style="width: 100%">
+  <div class="row">
+    <div class="col-md-pull-9 pull-left">
+      <p>
+        When you are using an Arvados virtual machine, you should clone the https:// URLs. This will authenticate automatically using your API token.
+      </p>
+      <p>
+        In order to clone git repositories using SSH, <%= link_to ssh_keys_user_path(current_user) do%> add an SSH key to your account<%end%> and clone the git@ URLs.
+      </p>
+    </div>
+    <div class="col-md-pull-3 pull-right">
+      <%= link_to raw('<i class="fa fa-plus"></i> Add new repository'), "#",
+                      {class: 'btn btn-xs btn-primary', 'data-toggle' => "modal",
+                       'data-target' => '#add-repository-modal'}  %>
+    </div>
+  </div>
+
+  <div>
+    <table class="table table-condensed table-fixedlayout repositories-table">
+      <colgroup>
+        <col style="width: 10%" />
+        <col style="width: 30%" />
+        <col style="width: 55%" />
+        <col style="width: 5%" />
+      </colgroup>
+      <thead>
+        <tr>
+          <th></th>
+          <th> Name </th>
+          <th> URL </th>
+          <th></th>
+        </tr>
+      </thead>
+
+      <tbody data-infinite-scroller="#repositories-rows" id="repositories-rows"
+        data-infinite-content-href="<%= url_for partial: :repositories_rows %>" >
+      </tbody>
+    </table>
+  </div>
+</div>
diff --git a/apps/workbench/app/views/repositories/_show_repositories_rows.html.erb b/apps/workbench/app/views/repositories/_show_repositories_rows.html.erb
new file mode 100644 (file)
index 0000000..3b322ad
--- /dev/null
@@ -0,0 +1,19 @@
+<% @objects.each do |repo| %>
+  <tr data-object-uuid="<%= repo.uuid %>">
+    <td>
+      <%= render :partial => "show_object_button", :locals => {object: repo, size: 'xs' } %>
+    </td>
+    <td style="word-break:break-all;">
+      <%= repo[:name] %>
+    </td>
+    <td style="word-break:break-all;">
+      <code><%= repo.http_fetch_url %></code><br/>
+      <code><%= repo.editable? ? repo.push_url : repo.fetch_url %></code>
+    </td>
+    <td>
+      <% if repo.editable? %>
+        <%= render partial: 'delete_object_button', locals: {object: repo} %>
+      <% end %>
+    </td>
+  </tr>
+<% end %>
diff --git a/apps/workbench/app/views/users/_repositories.html.erb b/apps/workbench/app/views/users/_repositories.html.erb
deleted file mode 100644 (file)
index 057b6a2..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-<%# Copyright (C) The Arvados Authors. All rights reserved.
-
-SPDX-License-Identifier: AGPL-3.0 %>
-
-<div class="panel panel-default">
-  <div class="panel-heading">
-    <div class="pull-right">
-      <%= link_to raw('<i class="fa fa-plus"></i> Add new repository'), "#",
-                   {class: 'btn btn-xs btn-primary', 'data-toggle' => "modal",
-                    'data-target' => '#add-repository-modal'}  %>
-    </div>
-    <h4 class="panel-title">
-      <%= link_to repositories_user_path(current_user) do%>
-        Repositories
-      <%end%>
-    </h4>
-  </div>
-
-  <div id="manage_repositories" class="panel-body">
-    <p>
-      When you are using an Arvados virtual machine, you should clone the https:// URLs. This will authenticate automatically using your API token.
-    </p>
-    <p>
-      In order to clone git repositories using SSH, <%= link_to ssh_keys_user_path(current_user) do%> add an SSH key to your account<%end%> and clone the git@ URLs.
-    </p>
-
-    <% if !@my_repositories.any? %>
-      You do not seem to have access to any repositories. If you would like to request access, please contact your system admin.
-    <% else %>
-      <table class="table repositories-table">
-        <colgroup>
-          <col style="width: 5%" />
-          <col style="width: 30%" />
-          <col style="width: 60%" />
-          <col style="width: 5%" />
-        </colgroup>
-        <thead>
-          <tr>
-            <th></th>
-            <th> Name </th>
-            <th> URL </th>
-            <th></th>
-          </tr>
-        </thead>
-        <tbody>
-          <% @my_repositories.andand.each do |repo| %>
-            <tr>
-              <td>
-                <%= render :partial => "show_object_button", :locals => {object: repo, size: 'xs' } %>
-              </td>
-              <td style="word-break:break-all;">
-                <%= repo[:name] %>
-              </td>
-              <td style="word-break:break-all;">
-                <code><%= repo.http_fetch_url %></code><br/>
-                <code><%= @repo_writable[repo.uuid] ? repo.push_url : repo.fetch_url %></code>
-              </td>
-              <td>
-                <% if repo.editable? %>
-                    <%= link_to(repository_path(id: repo.uuid), method: :delete, class: 'btn btn-sm', data: {confirm: "Really delete '#{repo.name || repo.uuid}'?"}) do %>
-                        <i class="fa fa-fw fa-trash-o"></i>
-                    <% end %>
-                <% end %>
-              </td>
-            </tr>
-          <% end %>
-        </tbody>
-      </table>
-    <% end %>
-  </div>
-</div>
diff --git a/apps/workbench/app/views/users/repositories.html.erb b/apps/workbench/app/views/users/repositories.html.erb
deleted file mode 100644 (file)
index 8a1a3b9..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<%# Copyright (C) The Arvados Authors. All rights reserved.
-
-SPDX-License-Identifier: AGPL-3.0 %>
-
-<%= render :partial => 'repositories' %>
-<%= render partial: "add_repository_modal" %>
index 561723da540bfff1fcfb0aac80dfbe4faaf48042..99e7285b3ba150eaa05d0ba0adc5809a744c832c 100644 (file)
@@ -125,4 +125,20 @@ class RepositoriesControllerTest < ActionController::TestCase
       assert_select 'tr td', 'COPYING'
     end
   end
+
+  test "get repositories lists linked as well as owned repositories" do
+    params = {
+      partial: :repositories_rows,
+      format: :json,
+    }
+    get :index, params, session_for(:active)
+    assert_response :success
+    repos = assigns(:objects)
+    assert repos
+    assert_not_empty repos, "my_repositories should not be empty"
+    repo_uuids = repos.map(&:uuid)
+    assert_includes repo_uuids, api_fixture('repositories')['repository2']['uuid']  # owned by active
+    assert_includes repo_uuids, api_fixture('repositories')['repository4']['uuid']  # shared with active
+    assert_includes repo_uuids, api_fixture('repositories')['arvados']['uuid']      # shared with all_users
+  end
 end
index ee64969f76461b618f93561e65e19d972ff79689..ce9282ff77d1e69450c864d8a09f70ec2d8637e7 100644 (file)
@@ -35,29 +35,6 @@ class UsersControllerTest < ActionController::TestCase
     assert_match /\/users\/welcome/, @response.redirect_url
   end
 
-  test "show repositories with read, write, or manage permission" do
-    get :repositories, {id: api_fixture("users")['active']['uuid']}, session_for(:active)
-    assert_response :success
-    repos = assigns(:my_repositories)
-    assert repos
-    assert_not_empty repos, "my_repositories should not be empty"
-    editables = repos.collect { |r| !!assigns(:repo_writable)[r.uuid] }
-    assert_includes editables, true, "should have a writable repository"
-    assert_includes editables, false, "should have a readonly repository"
-  end
-
-  test "show repositories lists linked as well as owned repositories" do
-    get :repositories, {id: api_fixture("users")['active']['uuid']}, session_for(:active)
-    assert_response :success
-    repos = assigns(:my_repositories)
-    assert repos
-    assert_not_empty repos, "my_repositories should not be empty"
-    repo_uuids = repos.map(&:uuid)
-    assert_includes repo_uuids, api_fixture('repositories')['repository2']['uuid']  # owned by active
-    assert_includes repo_uuids, api_fixture('repositories')['repository4']['uuid']  # shared with active
-    assert_includes repo_uuids, api_fixture('repositories')['arvados']['uuid']      # shared with all_users
-  end
-
   test "request shell access" do
     user = api_fixture('users')['spectator']
 
index e777ebe784272a065513f5bf7aa708deae5cd755..7692d8e5dc1b0df9a50c1dae8d258eb298e36e33 100644 (file)
@@ -56,7 +56,7 @@ class ApplicationLayoutTest < ActionDispatch::IntegrationTest
 
             assert_selector "a[href=\"/projects/#{user['uuid']}\"]", text: 'Home project'
             assert_selector "a[href=\"/users/#{user['uuid']}/virtual_machines\"]", text: 'Virtual machines'
-            assert_selector "a[href=\"/users/#{user['uuid']}/repositories\"]", text: 'Repositories'
+            assert_selector "a[href=\"/repositories\"]", text: 'Repositories'
             assert_selector "a[href=\"/current_token\"]", text: 'Current token'
             assert_selector "a[href=\"/users/#{user['uuid']}/ssh_keys\"]", text: 'SSH keys'
 
@@ -214,7 +214,7 @@ class ApplicationLayoutTest < ActionDispatch::IntegrationTest
   end
 
    [
-    ['Repositories', nil, 's0uqq'],
+    ['Repositories', nil, 'active/crunchdispatchtest'],
     ['Virtual machines', nil, 'testvm.shell'],
     ['SSH keys', nil, 'public_key'],
     ['Links', nil, 'link_class'],
index 75009f709c311ee3b65acf2c7af548a072ac2164..6a0e46e26aea5b6455fd400ac73d55596ab5895b 100644 (file)
@@ -114,7 +114,7 @@ class UserSettingsMenuTest < ActionDispatch::IntegrationTest
   end
 
   test "verify repositories for active user" do
-    visit page_with_token('active',"/users/#{api_fixture('users')['active']['uuid']}/repositories")
+    visit page_with_token('active',"/repositories")
 
     repos = [[api_fixture('repositories')['foo'], true],
              [api_fixture('repositories')['repository3'], false],
@@ -126,9 +126,9 @@ class UserSettingsMenuTest < ActionDispatch::IntegrationTest
         assert_text repo['name']
         assert_selector 'a', text:'Show'
         if owned
-          assert_not_nil first('.fa-trash-o')
+          assert_not_nil first('.glyphicon-trash')
         else
-          assert_nil first('.fa-trash-o')
+          assert_nil first('.glyphicon-trash')
         end
       end
     end
@@ -193,12 +193,12 @@ class UserSettingsMenuTest < ActionDispatch::IntegrationTest
 
   [
     ['virtual_machines', nil, 'Host name', 'testvm2.shell'],
-    ['repositories', 'Add new repository', 'It may take a minute or two before you can clone your new repository.', 'active/foo'],
+    ['/repositories', 'Add new repository', 'It may take a minute or two before you can clone your new repository.', 'active/foo'],
     ['/current_token', nil, 'HISTIGNORE=$HISTIGNORE', 'ARVADOS_API_TOKEN=3kg6k6lzmp9kj5'],
     ['ssh_keys', 'Add new SSH key', 'Click here to learn about SSH keys in Arvados.', 'active'],
   ].each do |page_name, button_name, look_for, content|
     test "test user settings menu for page #{page_name}" do
-      if page_name == '/current_token'
+      if page_name == '/current_token' || page_name == '/repositories'
         visit page_with_token('active', page_name)
       else
         visit page_with_token('active', "/users/#{api_fixture('users')['active']['uuid']}/#{page_name}")
@@ -216,7 +216,7 @@ class UserSettingsMenuTest < ActionDispatch::IntegrationTest
 
   [
     ['virtual_machines', 'You do not have access to any virtual machines.'],
-    ['/repositories', api_fixture('repositories')['arvados']['uuid']],
+    ['/repositories', api_fixture('repositories')['arvados']['name']],
     ['/current_token', 'HISTIGNORE=$HISTIGNORE'],
     ['ssh_keys', 'You have not yet set up an SSH public key for use with Arvados.'],
   ].each do |page_name, look_for|