1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 window.components = window.components || {}
6 window.components.collection_table = {
7 maybeLoadMore: function(dom) {
8 var loader = this.loader
9 if (loader.done || loader.loading)
10 // Can't start getting more items anyway: no point in
11 // checking anything else.
13 var contentRect = dom.getBoundingClientRect()
14 var scroller = window // TODO: use dom's nearest ancestor with scrollbars
15 if (contentRect.bottom < 2 * scroller.innerHeight) {
16 // We have less than 1 page worth of content available
17 // below the visible area. Load more.
19 // Indicate loading is in progress.
20 window.requestAnimationFrame(m.redraw)
23 oncreate: function(vnode) {
24 vnode.state.maybeLoadMore = vnode.state.maybeLoadMore.bind(vnode.state, vnode.dom)
25 window.addEventListener('scroll', vnode.state.maybeLoadMore)
26 window.addEventListener('resize', vnode.state.maybeLoadMore)
27 vnode.state.timer = window.setInterval(vnode.state.maybeLoadMore, 200)
28 vnode.state.loader = vnode.attrs.loader
29 vnode.state.onupdate(vnode)
31 onupdate: function(vnode) {
32 vnode.state.loader = vnode.attrs.loader
34 onremove: function(vnode) {
35 window.clearInterval(vnode.state.timer)
36 window.removeEventListener('scroll', vnode.state.maybeLoadMore)
37 window.removeEventListener('resize', vnode.state.maybeLoadMore)
39 view: function(vnode) {
40 return m('table.table.table-condensed', [
45 m('th', 'last modified'),
48 vnode.attrs.loader.items() && vnode.attrs.loader.items().map(function(item) {
50 m('td', m('a.btn.btn-xs.btn-default', {href: item.session.baseURL.replace('://', '://workbench.')+'collections/'+item.uuid}, 'Show')),
51 m('td.arvados-uuid', item.uuid),
52 m('td', item.name || '(unnamed)'),
53 m('td', m(window.components.datetime, {parse: item.modified_at})),
58 vnode.attrs.loader.done ? null : m('th[colspan=4]', m('button.btn.btn-xs', {
59 className: vnode.attrs.loader.loading ? 'btn-default' : 'btn-primary',
66 disabled: vnode.attrs.loader.loading,
68 vnode.attrs.loader.loadMore()
71 }, vnode.attrs.loader.loading ? '(loading)' : 'Load more')),
77 window.components.collection_search = {
78 oninit: function(vnode) {
79 vnode.state.sessionDB = new window.models.SessionDB()
80 vnode.state.searchEntered = m.stream()
81 vnode.state.searchActive = m.stream()
82 // When searchActive changes (e.g., when restoring state
83 // after navigation), update the text field too.
84 vnode.state.searchActive.map(vnode.state.searchEntered)
85 // When searchActive changes, create a new loader that filters
86 // with the given search term.
87 vnode.state.searchActive.map(function(q) {
88 var sessions = vnode.state.sessionDB.loadActive()
89 vnode.state.loader = new window.models.MergingLoader({
90 children: Object.keys(sessions).map(function(key) {
91 var session = sessions[key]
92 return new window.models.MultipageLoader({
93 loadFunc: function(filters) {
95 filters.push(['any', '@@', q+':*'])
96 return vnode.state.sessionDB.request(session, 'arvados/v1/collections', {
98 filters: JSON.stringify(filters),
101 }).then(function(resp) {
102 resp.items.map(function(item) {
103 item.session = session
113 view: function(vnode) {
114 var sessions = vnode.state.sessionDB.loadAll()
116 onsubmit: function() {
117 vnode.state.searchActive(vnode.state.searchEntered())
118 vnode.state.forgetSavedState = true
122 m(window.components.save_state, {
124 currentState: vnode.state.searchActive,
125 forgetSavedState: vnode.state.forgetSavedState,
126 saveBodyHeight: true,
128 vnode.state.loader && [
132 m('input#search.form-control[placeholder=Search]', {
133 oninput: m.withAttr('value', vnode.state.searchEntered),
134 value: vnode.state.searchEntered(),
136 m('.input-group-btn', [
137 m('input.btn.btn-primary[type=submit][value="Search"]'),
143 Object.keys(sessions).length == 0
144 ? m('span.label.label-xs.label-danger', 'none')
145 : Object.keys(sessions).sort().map(function(key) {
146 return [m('span.label.label-xs', {
147 className: !vnode.state.loader.children[key] ? 'label-default' :
148 vnode.state.loader.children[key].items() ? 'label-success' :
153 m('a[href="/sessions"]', 'Add/remove sites'),
156 m(window.components.collection_table, {
157 loader: vnode.state.loader,