12033: Add /collections/multisite search page.
authorTom Clegg <tom@curoverse.com>
Wed, 9 Aug 2017 01:34:39 +0000 (21:34 -0400)
committerTom Clegg <tom@curoverse.com>
Wed, 9 Aug 2017 01:34:39 +0000 (21:34 -0400)
Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom@curoverse.com>

apps/workbench/app/assets/javascripts/components/collections.js [new file with mode: 0644]
apps/workbench/app/assets/javascripts/models/session_db.js
apps/workbench/app/controllers/collections_controller.rb
apps/workbench/app/views/collections/multisite.html [new file with mode: 0644]
apps/workbench/config/routes.rb

diff --git a/apps/workbench/app/assets/javascripts/components/collections.js b/apps/workbench/app/assets/javascripts/components/collections.js
new file mode 100644 (file)
index 0000000..5bd667a
--- /dev/null
@@ -0,0 +1,107 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+window.components = window.components || {}
+window.components.collection_table_narrow = {
+    view: function(vnode) {
+        return m('table.table.table-condensed', [
+            m('thead', m('tr', m('th', vnode.attrs.key))),
+            m('tbody', [
+                vnode.attrs.items().map(function(item) {
+                    return m('tr', [
+                        m('td', [
+                            m('a', {href: '/collections/'+item.uuid}, item.name || '(unnamed)'),
+                            m('br'),
+                            item.modified_at,
+                        ]),
+                    ])
+                }),
+            ]),
+        ])
+    },
+}
+
+window.components.collection_search = {
+    oninit: function(vnode) {
+        vnode.state.sessionDB = new window.models.SessionDB()
+        vnode.state.searchEntered = m.stream('')
+        vnode.state.searchStart = m.stream('')
+        vnode.state.items = {}
+        vnode.state.searchStart.map(function(q) {
+            var sessions = vnode.state.sessionDB.loadAll()
+            var cookie = (new Date()).getTime()
+            vnode.state.cookie = cookie
+            Object.keys(sessions).map(function(key) {
+                if (!vnode.state.items[key])
+                    vnode.state.items[key] = m.stream([])
+                vnode.state.sessionDB.request(sessions[key], 'arvados/v1/collections', {
+                    data: {
+                        filters: JSON.stringify(!q ? [] : [['any', '@@', q+':*']]),
+                    },
+                }).then(function(resp) {
+                    if (cookie !== vnode.state.cookie)
+                        // a newer query is in progress; ignore this result.
+                        return
+                    vnode.state.items[key](resp.items)
+                })
+            })
+        })
+    },
+    view: function(vnode) {
+        var items = vnode.state.items
+        return m('form', {
+            onsubmit: function() {
+                vnode.state.searchStart(vnode.state.searchEntered())
+                return false
+            },
+        }, [
+            m('.row', [
+                m('.col-md-6', [
+                    m('.input-group', [
+                        m('input#search.form-control[placeholder=Search]', {
+                            oninput: m.withAttr('value', debounce(200, vnode.state.searchEntered)),
+                        }),
+                        m('.input-group-btn', [
+                            m('input.btn.btn-primary[type=submit][value="Search"]'),
+                        ]),
+                    ]),
+                ]),
+                m('.col-md-6', [
+                    'Searching sites: ',
+                    Object.keys(items).length == 0
+                        ? m('span.label.label-xs.label-danger', 'none')
+                        : Object.keys(items).sort().map(function(key) {
+                            return [m('span.label.label-xs.label-info', key), ' ']
+                        }),
+                    ' ',
+                    m('a[href="/sessions"]', 'Add/remove sites'),
+                ]),
+            ]),
+            m('.row', Object.keys(items).sort().map(function(key) {
+                return m('.col-md-3', {key: key}, [
+                    m(window.components.collection_table_narrow, {key: key, items: items[key]}),
+                ])
+            })),
+        ])
+    },
+}
+
+function debounce(t, f) {
+    // Return a new function that waits until t milliseconds have
+    // passed since it was last called, then calls f with its most
+    // recent arguments.
+    var this_was = this
+    var pending
+    return function() {
+        var args = arguments
+        if (pending) {
+            console.log("debounce!")
+            window.clearTimeout(pending)
+        }
+        pending = window.setTimeout(function() {
+            pending = undefined
+            f.apply(this_was, args)
+        }, t)
+    }
+}
index 058d450287f9033a3d54e39ebd24cfe1f0273007..75fe6f9e17206850596b237e0e55dec3418806ca 100644 (file)
@@ -79,5 +79,11 @@ window.models.SessionDB = function() {
             })
             // m.request(session.baseURL + 'discovery/v1/apis/arvados/v1/rest').then(function(dd) {})
         },
+        request: function(session, path, opts) {
+            opts = opts || {}
+            opts.headers = opts.headers || {}
+            opts.headers.authorization = 'OAuth2 '+ session.token
+            return m.request(session.baseURL + path, opts)
+        },
     })
 }
index f8fcf5108f025659bf5058f2861ef42d2e1b5781..da7b4666a03c753f8f4876753ac585e446fb33ad 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])
+                     only: [:provenance, :show_file, :show_file_links, :multisite])
   # 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
diff --git a/apps/workbench/app/views/collections/multisite.html b/apps/workbench/app/views/collections/multisite.html
new file mode 100644 (file)
index 0000000..7e49ac9
--- /dev/null
@@ -0,0 +1,5 @@
+<!-- Copyright (C) The Arvados Authors. All rights reserved.
+
+SPDX-License-Identifier: AGPL-3.0 -->
+
+<div data-mount-mithril="collection_search"></div>
index 8fde2b8f77b229ff1870d8994497350c6658eb3a..8dcc7fdd20cadbf41bb9da7997c06597169e29eb 100644 (file)
@@ -95,6 +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
   end
   get('/collections/download/:uuid/:reader_token/*file' => 'collections#show_file',
       format: false)