Merge branch '12519-multisite-project-search'
authorLucas Di Pentima <ldipentima@veritasgenetics.com>
Thu, 23 Nov 2017 19:22:21 +0000 (16:22 -0300)
committerLucas Di Pentima <ldipentima@veritasgenetics.com>
Thu, 23 Nov 2017 19:22:41 +0000 (16:22 -0300)
Closes #12519

Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <ldipentima@veritasgenetics.com>

apps/workbench/app/assets/javascripts/components/search.js [moved from apps/workbench/app/assets/javascripts/components/collections.js with 68% similarity]
apps/workbench/app/assets/javascripts/components/sessions.js
apps/workbench/app/assets/javascripts/models/session_db.js
apps/workbench/app/controllers/collections_controller.rb
apps/workbench/app/controllers/search_controller.rb
apps/workbench/app/views/layouts/body.html.erb
apps/workbench/app/views/search/index.html [moved from apps/workbench/app/views/collections/multisite.html with 66% similarity]
apps/workbench/config/routes.rb

similarity index 68%
rename from apps/workbench/app/assets/javascripts/components/collections.js
rename to apps/workbench/app/assets/javascripts/components/search.js
index 591bf38aa74b162e353c9705da1ecbcbba2d8cde..2fe73193e7f116fcda6c2831c8c2250c2a266aee 100644 (file)
@@ -2,7 +2,7 @@
 //
 // SPDX-License-Identifier: AGPL-3.0
 
-window.CollectionsTable = {
+window.SearchResultsTable = {
     maybeLoadMore: function(dom) {
         var loader = this.loader
         if (loader.state != loader.READY)
@@ -37,6 +37,10 @@ window.CollectionsTable = {
     },
     view: function(vnode) {
         var loader = vnode.attrs.loader
+        var iconsMap = {
+            collections: m('i.fa.fa-fw.fa-archive'),
+            projects: m('i.fa.fa-fw.fa-folder'),
+        }
         return m('table.table.table-condensed', [
             m('thead', m('tr', [
                 m('th'),
@@ -50,8 +54,13 @@ window.CollectionsTable = {
                         m('td', [
                             item.workbenchBaseURL() &&
                                 m('a.btn.btn-xs.btn-default', {
-                                    href: item.workbenchBaseURL()+'collections/'+item.uuid,
-                                }, 'Show'),
+                                    'data-original-title': 'show '+item.objectType.description,
+                                    'data-placement': 'top',
+                                    'data-toggle': 'tooltip',
+                                    href: item.workbenchBaseURL()+'/'+item.objectType.wb_path+'/'+item.uuid,
+                                    // Bootstrap's tooltip feature
+                                    oncreate: function(vnode) { $(vnode.dom).tooltip() },
+                                }, iconsMap[item.objectType.wb_path]),
                         ]),
                         m('td.arvados-uuid', item.uuid),
                         m('td', item.name || '(unnamed)'),
@@ -79,7 +88,7 @@ window.CollectionsTable = {
     },
 }
 
-window.CollectionsSearch = {
+window.Search = {
     oninit: function(vnode) {
         vnode.state.sessionDB = new SessionDB()
         vnode.state.searchEntered = m.stream()
@@ -97,28 +106,50 @@ window.CollectionsSearch = {
                     var workbenchBaseURL = function() {
                         return vnode.state.sessionDB.workbenchBaseURL(session)
                     }
-                    return new MultipageLoader({
+                    var searchable_objects = [
+                        {
+                            wb_path: 'projects',
+                            api_path: 'arvados/v1/groups',
+                            filters: [['group_class', '=', 'project']],
+                            description: 'project',
+                        },
+                        {
+                            wb_path: 'collections',
+                            api_path: 'arvados/v1/collections',
+                            filters: [],
+                            description: 'collection',
+                        },
+                    ]
+                    return new MergingLoader({
                         sessionKey: key,
-                        loadFunc: function(filters) {
-                            var tsquery = to_tsquery(q)
-                            if (tsquery) {
-                                filters = filters.slice(0)
-                                filters.push(['any', '@@', tsquery])
-                            }
-                            return vnode.state.sessionDB.request(session, 'arvados/v1/collections', {
-                                data: {
-                                    filters: JSON.stringify(filters),
-                                    count: 'none',
+                        // For every session, search for every object type
+                        children: searchable_objects.map(function(obj_type) {
+                            return new MultipageLoader({
+                                sessionKey: key,
+                                loadFunc: function(filters) {
+                                    // Apply additional type dependant filters
+                                    filters = filters.concat(obj_type.filters)
+                                    var tsquery = to_tsquery(q)
+                                    if (tsquery) {
+                                        filters.push(['any', '@@', tsquery])
+                                    }
+                                    return vnode.state.sessionDB.request(session, obj_type.api_path, {
+                                        data: {
+                                            filters: JSON.stringify(filters),
+                                            count: 'none',
+                                        },
+                                    }).then(function(resp) {
+                                        resp.items.map(function(item) {
+                                            item.workbenchBaseURL = workbenchBaseURL
+                                            item.objectType = obj_type
+                                        })
+                                        return resp
+                                    })
                                 },
-                            }).then(function(resp) {
-                                resp.items.map(function(item) {
-                                    item.workbenchBaseURL = workbenchBaseURL
-                                })
-                                return resp
                             })
-                        },
+                        }),
                     })
-                })
+                }),
             })
         })
     },
@@ -141,7 +172,7 @@ window.CollectionsSearch = {
                 m('.row', [
                     m('.col-md-6', [
                         m('.input-group', [
-                            m('input#search.form-control[placeholder=Search]', {
+                            m('input#search.form-control[placeholder=Search collections and projects]', {
                                 oninput: m.withAttr('value', vnode.state.searchEntered),
                                 value: vnode.state.searchEntered(),
                             }),
@@ -163,7 +194,7 @@ window.CollectionsSearch = {
                         m('a[href="/sessions"]', 'Add/remove sites'),
                     ]),
                 ]),
-                m(CollectionsTable, {
+                m(SearchResultsTable, {
                     loader: vnode.state.loader,
                 }),
             ],
index 3d127f1714d58a98eac115eeba96d9ebf95d39d4..e7cc5055734d4edaa2144d7eb4d704ec7e737736 100644 (file)
@@ -21,8 +21,8 @@ window.SessionsTable = {
         return m('.container', [
             m('p', [
                 'You can log in to multiple Arvados sites here, then use the ',
-                m('a[href="/collections/multisite"]', 'multi-site search'),
-                ' page to search collections on all sites at once.',
+                m('a[href="/search"]', 'multi-site search'),
+                ' page to search collections and projects on all sites at once.',
             ]),
             m('table.table.table-condensed.table-hover', [
                 m('thead', m('tr', [
index 01b0d72728c17d9531665058d397857ff3fa3b99..ad9ad1878417370dfd75294e9bd9cecbe25880d1 100644 (file)
@@ -135,7 +135,9 @@ window.SessionDB = function() {
             // the host part of apihostport is an IPv4 or [IPv6]
             // address.
             if (!session.baseURL.match('://(\\[|\\d+\\.\\d+\\.\\d+\\.\\d+[:/])'))
-                return session.baseURL.replace('://', '://workbench.')
+                var wbUrl = session.baseURL.replace('://', '://workbench.')
+                // Remove the trailing slash, if it's there.
+                return wbUrl.slice(-1) == '/' ? wbUrl.slice(0, -1) : wbUrl
             return null
         },
         // Return a m.stream that will get fulfilled with the
index 779d95c45b874d4fec157768e19013a1c68a0022..5fcb2dc569ff6b2446c602dc26de61a069155ba2 100644 (file)
@@ -16,7 +16,7 @@ class CollectionsController < ApplicationController
   skip_around_filter(:require_thread_api_token,
                      only: [:show_file, :show_file_links])
   skip_before_filter(:find_object_by_uuid,
-                     only: [:provenance, :show_file, :show_file_links, :multisite])
+                     only: [:provenance, :show_file, :show_file_links])
   # We depend on show_file to display the user agreement:
   skip_before_filter :check_user_agreements, only: :show_file
   skip_before_filter :check_user_profile, only: :show_file
index 40e484ea062b449068923fdc8d9951f1f7adddbe..3775abd1ae9f1117926d7bde8c847fc32ad0cd60 100644 (file)
@@ -3,6 +3,8 @@
 # SPDX-License-Identifier: AGPL-3.0
 
 class SearchController < ApplicationController
+  skip_before_filter :ensure_arvados_api_exists
+
   def find_objects_for_index
     search_what = Group
     if params[:project_uuid]
index 15f654596cbb501e8e86ccb24138d986c2f625e3..c1399f2602dc151907253d080af08504a53c0875 100644 (file)
@@ -34,7 +34,7 @@ SPDX-License-Identifier: AGPL-3.0 %>
                     <%=
                        target = Rails.configuration.multi_site_search
                        if target == true
-                         target = {controller: 'collections', action: 'multisite'}
+                         target = {controller: 'search', action: 'index'}
                        end
                        link_to("Multi-site search", target, {class: 'btn btn-default'}) %>
                   </form>
similarity index 66%
rename from apps/workbench/app/views/collections/multisite.html
rename to apps/workbench/app/views/search/index.html
index 9b03f10f3dcd90f6fd14d4d730367359be620797..6bcad0b1ae2c245ccd9b65afda7d3eac373088a7 100644 (file)
@@ -2,4 +2,4 @@
 
 SPDX-License-Identifier: AGPL-3.0 -->
 
-<div data-mount-mithril="CollectionsSearch"></div>
+<div data-mount-mithril="Search"></div>
index fee49c14ce213aa2cd001252043f4cc7dfc79745..d969abd78c2b69d8de936e2a00df0c0d1f1ef0f1 100644 (file)
@@ -95,7 +95,7 @@ ArvadosWorkbench::Application.routes.draw do
     post 'remove_selected_files', on: :member
     get 'tags', on: :member
     post 'save_tags', on: :member
-    get 'multisite', on: :collection
+    get 'multisite', on: :collection, to: redirect('/search')
   end
   get('/collections/download/:uuid/:reader_token/*file' => 'collections#show_file',
       format: false)
@@ -109,7 +109,7 @@ ArvadosWorkbench::Application.routes.draw do
     get 'tab_counts', on: :member
     get 'public', on: :collection
   end
-
+  
   resources :search do
     get 'choose', :on => :collection
   end
@@ -131,9 +131,9 @@ ArvadosWorkbench::Application.routes.draw do
   match '/_health/ping', to: 'healthcheck#ping', via: [:get]
 
   get '/tests/mithril', to: 'tests#mithril'
-
+  
   get '/status', to: 'status#status'
-
+  
   # Send unroutable requests to an arbitrary controller
   # (ends up at ApplicationController#render_not_found)
   match '*a', to: 'links#render_not_found', via: [:get, :post]