From 0ba2f540b4f635020f5e220cfa2b40dcb84be858 Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Mon, 1 Feb 2021 11:45:54 +0100 Subject: [PATCH 1/9] Decrease verbosity of urllib connectinpool logging --- lib/galaxy/config/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/galaxy/config/__init__.py b/lib/galaxy/config/__init__.py index 353510c68eb..d026720c1e4 100644 --- a/lib/galaxy/config/__init__.py +++ b/lib/galaxy/config/__init__.py @@ -66,6 +66,10 @@ LOGGING_CONFIG_DEFAULT = { 'level': 'WARN', 'qualname': 'paste.httpserver.ThreadPool', }, + 'urllib3.connectionpool': { + 'level': 'WARN', + 'qualname': 'urllib3.connectionpool', + }, 'routes.middleware': { 'level': 'WARN', 'qualname': 'routes.middleware', From dd4de637c72e86fead98e1c6a2d23d5b1a3e8b0d Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Mon, 1 Feb 2021 15:40:31 +0100 Subject: [PATCH 2/9] Fix dbkey setup Fixes vsnp* tool test failures (`Input staging problem: Invalid dbkey specified`) and https://sentry.galaxyproject.org/sentry/test/issues/44049/. Minor bug introduced in https://github.com/galaxyproject/galaxy/pull/10667/files. --- lib/galaxy/tools/parameters/basic.py | 7 +-- lib/galaxy/util/__init__.py | 53 ----------------------- lib/galaxy/util/dbkeys.py | 64 ++++++++++++++++++++++++++-- 3 files changed, 65 insertions(+), 59 deletions(-) diff --git a/lib/galaxy/tools/parameters/basic.py b/lib/galaxy/tools/parameters/basic.py index 4ec7dbb9836..9de12bfea84 100644 --- a/lib/galaxy/tools/parameters/basic.py +++ b/lib/galaxy/tools/parameters/basic.py @@ -15,6 +15,7 @@ import galaxy.model from galaxy import util from galaxy.tool_util.parser import get_input_source as ensure_input_source from galaxy.util import ( + dbkeys, sanitize_param, string_as_bool, string_as_bool_or_none, @@ -1038,7 +1039,7 @@ class GenomeBuildParameter(SelectToolParameter): >>> # Create a mock transaction with 'hg17' as the current build >>> from galaxy.util.bunch import Bunch - >>> trans = Bunch(app=None, history=Bunch(genome_build='hg17'), db_builds=util.read_dbnames(None)) + >>> trans = Bunch(app=None, history=Bunch(genome_build='hg17'), db_builds=dbkeys.read_dbnames(None)) >>> p = GenomeBuildParameter(None, XML('')) >>> print(p.name) _name @@ -1092,7 +1093,7 @@ class GenomeBuildParameter(SelectToolParameter): def _get_dbkey_names(self, trans=None): if not self.tool: # Hack for unit tests, since we have no tool - return util.read_dbnames(None) + return dbkeys.read_dbnames(None) return self.tool.app.genome_builds.get_genome_build_names(trans=trans) @@ -1388,7 +1389,7 @@ class DrillDownSelectToolParameter(SelectToolParameter): Creating a hierarchical select menu, which allows users to 'drill down' a tree-like set of options. >>> from galaxy.util.bunch import Bunch - >>> trans = Bunch(app=None, history=Bunch(genome_build='hg17'), db_builds=util.read_dbnames(None)) + >>> trans = Bunch(app=None, history=Bunch(genome_build='hg17'), db_builds=dbkeys.read_dbnames(None)) >>> p = DrillDownSelectToolParameter(None, XML( ... ''' ... diff --git a/lib/galaxy/util/__init__.py b/lib/galaxy/util/__init__.py index e65c00dc1f2..ce9f4c0260c 100644 --- a/lib/galaxy/util/__init__.py +++ b/lib/galaxy/util/__init__.py @@ -1168,59 +1168,6 @@ def compare_urls(url1, url2, compare_scheme=True, compare_hostname=True, compare return True -def read_dbnames(filename): - """ Read build names from file """ - db_names = [] - try: - ucsc_builds = {} - man_builds = [] # assume these are integers - name_to_db_base = {} - if filename is None: - # Should only be happening with the galaxy.tools.parameters.basic:GenomeBuildParameter docstring unit test - filename = os.path.join(galaxy_directory(), 'tool-data', 'shared', 'ucsc', 'builds.txt.sample') - for line in open(filename): - try: - if line[0:1] == "#": - continue - fields = line.replace("\r", "").replace("\n", "").split("\t") - # Special case of unspecified build is at top of list - if fields[0] == "?": - db_names.insert(0, (fields[0], fields[1])) - continue - try: # manual build (i.e. microbes) - int(fields[0]) - man_builds.append((fields[1], fields[0])) - except Exception: # UCSC build - db_base = fields[0].rstrip('0123456789') - if db_base not in ucsc_builds: - ucsc_builds[db_base] = [] - name_to_db_base[fields[1]] = db_base - # we want to sort within a species numerically by revision number - build_rev = re.compile(r'\d+$') - try: - build_rev = int(build_rev.findall(fields[0])[0]) - except Exception: - build_rev = 0 - ucsc_builds[db_base].append((build_rev, fields[0], fields[1])) - except Exception: - continue - sort_names = sorted(name_to_db_base.keys()) - for name in sort_names: - db_base = name_to_db_base[name] - ucsc_builds[db_base].sort() - ucsc_builds[db_base].reverse() - ucsc_builds[db_base] = [(build, name) for _, build, name in ucsc_builds[db_base]] - db_names = list(db_names + ucsc_builds[db_base]) - if len(db_names) > 1 and len(man_builds) > 0: - db_names.append((db_names.default_value, '----- Additional Species Are Below -----')) - man_builds.sort() - man_builds = [(build, name) for name, build in man_builds] - db_names = list(db_names + man_builds) - except Exception as e: - log.error("ERROR: Unable to read builds file: %s", unicodify(e)) - return db_names - - def read_build_sites(filename, check_builds=True): """ read db names to ucsc mappings from file, this file should probably be merged with the one above """ build_sites = [] diff --git a/lib/galaxy/util/dbkeys.py b/lib/galaxy/util/dbkeys.py index 926b67e9e31..27b4b1d4fcc 100644 --- a/lib/galaxy/util/dbkeys.py +++ b/lib/galaxy/util/dbkeys.py @@ -1,14 +1,72 @@ """ Functionality for dealing with dbkeys. """ -# dbkeys read from disk using builds.txt - +import logging import os.path +import re from json import loads -from galaxy.util import read_dbnames +from galaxy.util import ( + galaxy_directory, + unicodify, +) from galaxy.util.object_wrapper import sanitize_lists_to_string +log = logging.getLogger(__name__) + + +def read_dbnames(filename): + """ Read build names from file """ + db_names = [] + try: + ucsc_builds = {} + man_builds = [] # assume these are integers + name_to_db_base = {} + if filename is None: + # Should only be happening with the galaxy.tools.parameters.basic:GenomeBuildParameter docstring unit test + filename = os.path.join(galaxy_directory(), 'tool-data', 'shared', 'ucsc', 'builds.txt.sample') + for line in open(filename): + try: + if line[0:1] == "#": + continue + fields = line.replace("\r", "").replace("\n", "").split("\t") + # Special case of unspecified build is at top of list + if fields[0] == "?": + db_names.insert(0, (fields[0], fields[1])) + continue + try: # manual build (i.e. microbes) + int(fields[0]) + man_builds.append((fields[1], fields[0])) + except Exception: # UCSC build + db_base = fields[0].rstrip('0123456789') + if db_base not in ucsc_builds: + ucsc_builds[db_base] = [] + name_to_db_base[fields[1]] = db_base + # we want to sort within a species numerically by revision number + build_rev = re.compile(r'\d+$') + try: + build_rev = int(build_rev.findall(fields[0])[0]) + except Exception: + build_rev = 0 + ucsc_builds[db_base].append((build_rev, fields[0], fields[1])) + except Exception: + continue + sort_names = sorted(name_to_db_base.keys()) + for name in sort_names: + db_base = name_to_db_base[name] + ucsc_builds[db_base].sort() + ucsc_builds[db_base].reverse() + ucsc_builds[db_base] = [(build, name) for _, build, name in ucsc_builds[db_base]] + db_names = list(db_names + ucsc_builds[db_base]) + if len(db_names) > 1 and len(man_builds) > 0: + db_names.append((GenomeBuilds.default_value, '----- Additional Species Are Below -----')) + man_builds.sort() + man_builds = [(build, name) for name, build in man_builds] + db_names = list(db_names + man_builds) + except Exception as e: + log.error("ERROR: Unable to read builds file: %s", unicodify(e)) + return db_names + class GenomeBuilds: default_value = "?" From d8fd3ddfe8d6ba00cd509caf29078cbff7f3ff18 Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Mon, 1 Feb 2021 16:55:11 +0100 Subject: [PATCH 3/9] Set correct status code in old history route `err_code.code` is our internal error, more specific code that looks like `403003` for instance, while we need to set a standard webob.exc status code here. Fixes https://sentry.galaxyproject.org/sentry/test/issues/1216796/: ``` AttributeError: 'NoneType' object has no attribute 'code' File "galaxy/web/framework/middleware/sentry.py", line 43, in __call__ iterable = self.application(environ, start_response) File "/cvmfs/test.galaxyproject.org/venv/lib/python3.6/site-packages/paste/recursive.py", line 85, in __call__ return self.application(environ, start_response) File "galaxy/web/framework/middleware/statsd.py", line 33, in __call__ req = self.application(environ, start_response) File "/cvmfs/test.galaxyproject.org/venv/lib/python3.6/site-packages/paste/httpexceptions.py", line 640, in __call__ return self.application(environ, start_response) File "galaxy/web/framework/base.py", line 136, in __call__ return self.handle_request(environ, start_response) File "galaxy/web/framework/base.py", line 221, in handle_request return body_renderer(trans, body, environ, start_response) File "galaxy/web/framework/base.py", line 239, in _render_body start_response(trans.response.wsgi_status(), File "galaxy/web/framework/base.py", line 473, in wsgi_status return "%d %s" % (exception.code, exception.title) ``` --- lib/galaxy/webapps/galaxy/controllers/history.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/galaxy/webapps/galaxy/controllers/history.py b/lib/galaxy/webapps/galaxy/controllers/history.py index 3d83ea8dfbd..1adc7bbe97b 100644 --- a/lib/galaxy/webapps/galaxy/controllers/history.py +++ b/lib/galaxy/webapps/galaxy/controllers/history.py @@ -1208,7 +1208,7 @@ class HistoryController(BaseUIController, SharableMixin, UsesAnnotations, UsesIt trans.set_history(history) return self.history_data(trans, history) except exceptions.MessageException as msg_exc: - trans.response.status = msg_exc.err_code.code + trans.response.status = msg_exc.status_code return {'err_msg': msg_exc.err_msg, 'err_code': msg_exc.err_code.code} @web.json From 8e11ed5ebf8d0a695bac0419b885d5388b588cf1 Mon Sep 17 00:00:00 2001 From: davelopez <46503462+davelopez@users.noreply.github.com> Date: Tue, 2 Feb 2021 15:45:38 +0100 Subject: [PATCH 4/9] Fix error on Admin panel when creating new quota --- lib/galaxy/webapps/galaxy/controllers/admin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/galaxy/webapps/galaxy/controllers/admin.py b/lib/galaxy/webapps/galaxy/controllers/admin.py index 7fe0ca4de33..36b1e38e098 100644 --- a/lib/galaxy/webapps/galaxy/controllers/admin.py +++ b/lib/galaxy/webapps/galaxy/controllers/admin.py @@ -677,8 +677,8 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP .order_by(trans.app.model.Group.table.c.name): all_groups.append((group.name, trans.security.encode_id(group.id))) default_options = [('No', 'no')] - for typ in trans.app.model.DefaultQuotaAssociation.types.__dict__.values(): - default_options.append(('Yes, ' + typ, typ)) + for type_ in trans.app.model.DefaultQuotaAssociation.types: + default_options.append(('Yes, ' + type_, type_)) return {'title': 'Create Quota', 'inputs': [ { From 8afffbd2f99d18ebcdcc2989026f12d94fa100d0 Mon Sep 17 00:00:00 2001 From: Nate Coraor Date: Tue, 2 Feb 2021 17:20:15 -0500 Subject: [PATCH 5/9] Update pulsar lib to 0.14.1 --- lib/galaxy/dependencies/pipfiles/default/Pipfile | 2 +- .../dependencies/pipfiles/default/pinned-requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/galaxy/dependencies/pipfiles/default/Pipfile b/lib/galaxy/dependencies/pipfiles/default/Pipfile index 5804df16ea9..1e04dcf0216 100644 --- a/lib/galaxy/dependencies/pipfiles/default/Pipfile +++ b/lib/galaxy/dependencies/pipfiles/default/Pipfile @@ -75,7 +75,7 @@ bioblend = "*" boto = "*" kombu = "*" psutil = "*" -pulsar-galaxy-lib = "==0.14.0.dev4" +pulsar-galaxy-lib = "==0.14.1" sqlalchemy-migrate = "*" sqlitedict = "*" sqlparse = "*" diff --git a/lib/galaxy/dependencies/pipfiles/default/pinned-requirements.txt b/lib/galaxy/dependencies/pipfiles/default/pinned-requirements.txt index 09324d1cd95..a75bd2a035d 100644 --- a/lib/galaxy/dependencies/pipfiles/default/pinned-requirements.txt +++ b/lib/galaxy/dependencies/pipfiles/default/pinned-requirements.txt @@ -117,7 +117,7 @@ prettytable==0.7.2 protobuf==3.14.0 prov==1.5.1 psutil==5.7.3 -pulsar-galaxy-lib==0.14.0.dev4 +pulsar-galaxy-lib==0.14.1 pyasn1-modules==0.2.8 pyasn1==0.4.8 pycparser==2.20; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' From a72850ee75a5643e4b225f54700678d42005739a Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Wed, 3 Feb 2021 11:44:34 +0100 Subject: [PATCH 6/9] Don't check if item is in list Just do set intersection. This is surprisingly something that takes up a good amount of CPU time on job handlers if there are a lot of jobs. With cumulative line-based profiling this is one of the top lines in Galaxy code. --- lib/galaxy/jobs/handler.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/galaxy/jobs/handler.py b/lib/galaxy/jobs/handler.py index 4cff86a0308..4de1b62e7f5 100644 --- a/lib/galaxy/jobs/handler.py +++ b/lib/galaxy/jobs/handler.py @@ -436,9 +436,8 @@ class JobHandlerQueue(Monitors): if not self.track_jobs_in_database: self.waiting_jobs = new_waiting_jobs # Remove cached wrappers for any jobs that are no longer being tracked - for id in list(self.job_wrappers.keys()): - if id not in new_waiting_jobs: - del self.job_wrappers[id] + for id in set(self.job_wrappers.keys()) - set(new_waiting_jobs): + del self.job_wrappers[id] # Flush, if we updated the state self.sa_session.flush() # Done with the session From 60efa8e094b4b2e70f59b8edda7c87998e6ecd99 Mon Sep 17 00:00:00 2001 From: Mason Houtz Date: Wed, 3 Feb 2021 08:23:53 -0800 Subject: [PATCH 7/9] history load fixes, rxjs provider debugging, upload init isolation --- client/package.json | 2 +- .../src/components/DataDialog/DataDialog.vue | 4 +- client/src/components/DebouncedInput.js | 6 - .../ContentItem/CollectionContentItem.js | 6 - .../History/ContentItem/ContentItem.js | 32 +- .../History/ContentItem/Dataset/Dataset.vue | 57 +++ .../ContentItem/Dataset/DatasetMenu.vue | 31 +- .../History/ContentItem/Dataset/DatasetUI.vue | 61 ++- .../History/ContentItem/Dataset/index.js | 5 + .../History/ContentItem/Dataset/index.vue | 49 --- .../DatasetCollection/DatasetCollection.vue | 57 +++ .../ContentItem/DatasetCollection/DscMenu.vue | 6 +- .../ContentItem/DatasetCollection/DscUI.vue | 37 +- .../ContentItem/DatasetCollection/index.js | 6 + .../ContentItem/DatasetCollection/index.vue | 67 ---- .../History/ContentItem/HistoryContentItem.js | 4 - .../History/ContentItem/Subcollection.vue | 12 +- .../components/History/ContentOperations.vue | 6 +- client/src/components/History/CopyModal.vue | 13 +- .../Details.vue | 10 +- .../History/CurrentCollection/Panel.vue | 109 ++++++ .../TopNav.vue | 16 - .../History/CurrentHistoryPanel.vue | 54 +-- .../src/components/History/HistoriesMenu.vue | 53 +++ client/src/components/History/History.vue | 159 ++++---- .../src/components/History/HistoryDetails.vue | 125 +++--- .../src/components/History/HistoryEmpty.vue | 9 +- .../src/components/History/HistoryPanel.vue | 48 ++- .../components/History/HistorySelector.vue | 22 +- client/src/components/History/HistoryTags.vue | 2 +- .../src/components/History/HistoryTopNav.vue | 91 ----- client/src/components/History/ListMixin.js | 73 ---- .../History/SelectedCollection/Panel.vue | 123 ------ .../History/adapters/HistoryPanelProxy.js | 1 - .../src/components/History/caching/index.js | 1 + .../History/caching/loadDscContent.js | 5 +- .../src/components/History/caching/queue.js | 41 -- .../src/components/History/model/Content.js | 6 + .../components/History/model/historyStore.js | 213 +++++----- .../src/components/History/model/queries.js | 39 +- .../CollectionContentProvider.js | 172 +-------- .../CollectionContentProvider.test.js | 7 +- .../loadCollectionContents.js | 30 +- .../processCollectionStreams.js | 102 +++++ .../History/providers/ContentProvider.js | 38 +- .../providers/DscProvider/DscProvider.test.js | 7 +- .../History/providers/ExpandedItems.js | 39 ++ .../HistoryContentProvider.js | 342 +---------------- .../HistoryContentProvider.test.js | 6 +- .../processHistoryStreams.js | 224 +++++++++++ .../watchHistoryContents.js | 13 +- .../History/providers/SelectedItems.js | 86 +++++ .../components/History/providers/UpdateMap.js | 59 --- .../History/providers/UpdateMap.test.js | 56 --- .../UserHistories/MockCurrentHistory.js | 10 + .../providers/UserHistories/UserHistories.js | 95 +++++ .../UserHistories/UserHistories.test.js | 201 ++++++++++ .../History/providers/UserHistories/index.js | 2 + .../src/components/History/providers/index.js | 7 + .../components/Panels/Common/ToolSection.vue | 23 +- client/src/components/Panels/ToolBox.vue | 6 +- client/src/components/PriorityMenu/Menu.vue | 2 +- .../src/components/PriorityMenu/MenuItem.vue | 4 +- .../src/components/RuleCollectionBuilder.vue | 28 +- client/src/components/Tags/Tags.test.js | 11 +- client/src/components/Upload/Collection.vue | 10 +- client/src/components/Upload/Composite.vue | 8 +- client/src/components/Upload/Default.vue | 10 +- client/src/components/Upload/RulesInput.vue | 44 +-- .../Buttons => Upload}/UploadButton.vue | 33 +- .../src/components/Upload/UploadModal.test.js | 46 ++- client/src/components/Upload/UploadModal.vue | 363 +++--------------- .../components/Upload/UploadModalContent.vue | 243 ++++++++++++ client/src/components/Upload/config.js | 6 +- client/src/components/Upload/helpers.js | 52 +++ client/src/components/Upload/index.js | 5 +- client/src/components/Upload/mount.js | 34 +- .../DatasetCollectionUIWrapper.test.js | 8 +- .../DatasetCollectionUIWrapper.vue | 10 +- .../DatasetUIWrapper.test.js | 8 +- .../DatasetUIWrapper.vue | 24 +- .../WorkflowInvocationDetails.vue | 31 +- .../providers/rxProviders.js | 3 - client/src/components/plugins/eventHub.js | 2 +- client/src/components/plugins/index.js | 6 +- client/src/components/plugins/localization.js | 9 + .../components/providers/ConfigProvider.js | 23 ++ .../src/components/providers/CurrentUser.js | 18 + .../components/providers/MockCurrentUser.js | 9 + .../providers/SingleQueryProvider.js | 30 ++ client/src/entry/panels/tool-panel.js | 19 - .../mvc/history/history-view-edit-current.js | 4 +- client/src/mvc/upload/upload-utils.js | 71 ++-- client/src/store/configStore/configStore.js | 42 ++ client/src/store/configStore/index.js | 46 +-- .../store/configStore/syncConfigToGalaxy.js | 4 +- client/src/store/index.js | 16 +- client/src/store/syncVuextoGalaxy.js | 6 +- .../src/store/userStore/syncUserToGalaxy.js | 5 +- client/src/store/userStore/userStore.js | 24 +- client/src/utils/data.js | 5 +- client/src/utils/mountVueComponent.js | 4 +- client/src/utils/observable/activity.js | 36 +- client/src/utils/observable/debugging.js | 34 -- client/src/utils/observable/lastValueFrom.js | 15 - client/src/utils/observable/nth.js | 4 + client/src/utils/observable/shareButDie.js | 7 + client/src/utils/observable/waitForInit.js | 5 + client/src/utils/proxy.js | 57 +-- client/src/utils/redirect.js | 11 + client/src/utils/sorting.js | 15 + client/tests/jest/helpers.js | 10 +- 112 files changed, 2425 insertions(+), 2281 deletions(-) create mode 100644 client/src/components/History/ContentItem/Dataset/Dataset.vue create mode 100644 client/src/components/History/ContentItem/Dataset/index.js delete mode 100644 client/src/components/History/ContentItem/Dataset/index.vue create mode 100644 client/src/components/History/ContentItem/DatasetCollection/DatasetCollection.vue create mode 100644 client/src/components/History/ContentItem/DatasetCollection/index.js delete mode 100644 client/src/components/History/ContentItem/DatasetCollection/index.vue rename client/src/components/History/{SelectedCollection => CurrentCollection}/Details.vue (77%) create mode 100644 client/src/components/History/CurrentCollection/Panel.vue rename client/src/components/History/{SelectedCollection => CurrentCollection}/TopNav.vue (80%) create mode 100644 client/src/components/History/HistoriesMenu.vue delete mode 100644 client/src/components/History/HistoryTopNav.vue delete mode 100644 client/src/components/History/ListMixin.js delete mode 100644 client/src/components/History/SelectedCollection/Panel.vue delete mode 100644 client/src/components/History/caching/queue.js create mode 100644 client/src/components/History/providers/CollectionContentProvider/processCollectionStreams.js create mode 100644 client/src/components/History/providers/ExpandedItems.js create mode 100644 client/src/components/History/providers/HistoryContentProvider/processHistoryStreams.js create mode 100644 client/src/components/History/providers/SelectedItems.js delete mode 100644 client/src/components/History/providers/UpdateMap.js delete mode 100644 client/src/components/History/providers/UpdateMap.test.js create mode 100644 client/src/components/History/providers/UserHistories/MockCurrentHistory.js create mode 100644 client/src/components/History/providers/UserHistories/UserHistories.js create mode 100644 client/src/components/History/providers/UserHistories/UserHistories.test.js create mode 100644 client/src/components/History/providers/UserHistories/index.js rename client/src/components/{Panels/Buttons => Upload}/UploadButton.vue (61%) create mode 100644 client/src/components/Upload/UploadModalContent.vue create mode 100644 client/src/components/Upload/helpers.js create mode 100644 client/src/components/providers/ConfigProvider.js create mode 100644 client/src/components/providers/CurrentUser.js create mode 100644 client/src/components/providers/MockCurrentUser.js create mode 100644 client/src/components/providers/SingleQueryProvider.js create mode 100644 client/src/store/configStore/configStore.js delete mode 100644 client/src/utils/observable/debugging.js delete mode 100644 client/src/utils/observable/lastValueFrom.js create mode 100644 client/src/utils/observable/nth.js create mode 100644 client/src/utils/observable/shareButDie.js create mode 100644 client/src/utils/sorting.js diff --git a/client/package.json b/client/package.json index 7f3ac4610ed..04561397485 100644 --- a/client/package.json +++ b/client/package.json @@ -74,11 +74,11 @@ "underscore": "^1.10.2", "underscore.string": "^3.3.5", "vue": "^2.6.11", - "vuedraggable": "2.24.1", "vue-infinite-scroll": "^2.0.2", "vue-multiselect": "^2.1.0", "vue-router": "^3.3.1", "vue-rx": "^6.2.0", + "vuedraggable": "2.24.1", "vueisotope": "^3.1.2", "vuex": "^3.4.0", "vuex-cache": "^3.2.0", diff --git a/client/src/components/DataDialog/DataDialog.vue b/client/src/components/DataDialog/DataDialog.vue index f1b498fcde5..a123cda6429 100644 --- a/client/src/components/DataDialog/DataDialog.vue +++ b/client/src/components/DataDialog/DataDialog.vue @@ -49,7 +49,7 @@ import { UrlTracker } from "./utilities"; import { Model } from "./model"; import { Services } from "./services"; import { getAppRoot } from "onload/loadConfig"; -import { mountUploadModal } from "components/Upload"; +import { openUploadModal } from "components/Upload"; Vue.use(BootstrapVue); @@ -135,7 +135,7 @@ export default { callback: this.callback, modalShow: true, }; - mountUploadModal(propsData); + openUploadModal(propsData); this.modalShow = false; }, /** Called when selection is complete, values are formatted and parsed to external callback **/ diff --git a/client/src/components/DebouncedInput.js b/client/src/components/DebouncedInput.js index dd3e1cba62f..03a4ee9de5f 100644 --- a/client/src/components/DebouncedInput.js +++ b/client/src/components/DebouncedInput.js @@ -2,15 +2,9 @@ * Renderless component, used to debounce various types of form inputs */ -import Vue from "vue"; -import VueRx from "vue-rx"; import { filter, debounceTime, distinctUntilChanged, finalize } from "rxjs/operators"; -import { vueRxShortcuts } from "./plugins"; - -Vue.use(VueRx); export default { - mixins: [vueRxShortcuts], props: { value: { required: true }, delay: { type: Number, required: false, default: 500 }, diff --git a/client/src/components/History/ContentItem/CollectionContentItem.js b/client/src/components/History/ContentItem/CollectionContentItem.js index e88605af117..efa92a9083a 100644 --- a/client/src/components/History/ContentItem/CollectionContentItem.js +++ b/client/src/components/History/ContentItem/CollectionContentItem.js @@ -5,12 +5,6 @@ export default { computed: { contentItemComponent() { - if (this.item === null) { - return "Loading"; - } - if (this.scrolling) { - return "Placeholder"; - } const { history_content_type } = this.item; switch (history_content_type) { case "dataset": diff --git a/client/src/components/History/ContentItem/ContentItem.js b/client/src/components/History/ContentItem/ContentItem.js index afe62bf8e10..0adfea54b42 100644 --- a/client/src/components/History/ContentItem/ContentItem.js +++ b/client/src/components/History/ContentItem/ContentItem.js @@ -11,22 +11,17 @@ import Placeholder from "./Placeholder"; import Dataset from "./Dataset"; import DatasetCollection from "./DatasetCollection"; +// import SubDataset from "./SubDataset"; import Subcollection from "./Subcollection"; export default { - inject: ["listState", "isSelected", "isExpanded", "setSelected", "setExpanded"], - template: ` + + + + diff --git a/client/src/components/History/ContentItem/Dataset/DatasetMenu.vue b/client/src/components/History/ContentItem/Dataset/DatasetMenu.vue index bc96b65eba6..3982752bf4a 100644 --- a/client/src/components/History/ContentItem/Dataset/DatasetMenu.vue +++ b/client/src/components/History/ContentItem/Dataset/DatasetMenu.vue @@ -72,6 +72,14 @@ icon="fas fa-file-download" /> + +
import { mapGetters } from "vuex"; -import { Dataset } from "../../model"; +import { Dataset, STATES } from "../../model"; import { PriorityMenu, PriorityMenuItem } from "components/PriorityMenu"; -import { legacyNavigationMixin } from "components/plugins"; +import { legacyNavigationMixin } from "components/plugins/legacyNavigation"; export default { - inject: ["STATES"], mixins: [legacyNavigationMixin], components: { @@ -156,6 +163,11 @@ export default { }; }, + created() { + // make available to template + this.STATES = STATES; + }, + computed: { ...mapGetters("user", ["currentUser"]), ...mapGetters("config", ["config"]), @@ -168,10 +180,10 @@ export default { if (this.dataset.purged) { return "Cannot display datasets removed from disk"; } - if (this.dataset.state == this.STATES.UPLOAD) { + if (this.dataset.state == STATES.UPLOAD) { return "This dataset must finish uploading before it can be viewed"; } - if (this.dataset.state == this.STATES.NEW) { + if (this.dataset.state == STATES.NEW) { return "This dataset is not yet viewable"; } return "View data"; @@ -184,7 +196,7 @@ export default { if (this.dataset.purged) { return "Cannot edit attributes of datasets removed from disk"; } - const unreadyStates = new Set([this.STATES.UPLOAD, this.STATES.NEW]); + const unreadyStates = new Set([STATES.UPLOAD, STATES.NEW]); if (unreadyStates.has(this.dataset.state)) { return "This dataset is not yet editable"; } @@ -206,7 +218,7 @@ export default { if (!this.dataset.hasData) { return false; } - const okStates = new Set([this.STATES.OK, this.STATES.FAILED_METADATA, this.STATES.ERROR]); + const okStates = new Set([STATES.OK, STATES.FAILED_METADATA, STATES.ERROR]); return okStates.has(this.dataset.state); }, @@ -261,9 +273,8 @@ export default { }, onDeleteClick() { - const eventName = this.dataset.deleted ? "undeleteDataset" : "deleteDataset"; - // console.log("emitting", eventName, this.dataset); - this.$emit(eventName, this.dataset); + const eventName = this.dataset.deleted ? "undelete" : "delete"; + this.$emit(eventName); }, }, }; diff --git a/client/src/components/History/ContentItem/Dataset/DatasetUI.vue b/client/src/components/History/ContentItem/Dataset/DatasetUI.vue index 8314d8c6d92..36c2da3b28e 100644 --- a/client/src/components/History/ContentItem/Dataset/DatasetUI.vue +++ b/client/src/components/History/ContentItem/Dataset/DatasetUI.vue @@ -14,6 +14,7 @@ either through the props, and make updates through the events --> @keydown.arrow-right.self.stop="$emit('update:expanded', true)" @keydown.space.self.stop.prevent="$emit('update:selected', !selected)" > +
@@ -46,25 +46,30 @@ either through the props, and make updates through the events --> {{ dataset.hid }} {{ dataset.title }} - - + + + + +
+ +
+ +
- - - + +
+ +
@@ -102,20 +108,16 @@ either through the props, and make updates through the events --> diff --git a/client/src/components/History/ContentItem/DatasetCollection/DatasetCollection.vue b/client/src/components/History/ContentItem/DatasetCollection/DatasetCollection.vue new file mode 100644 index 00000000000..86e54a534df --- /dev/null +++ b/client/src/components/History/ContentItem/DatasetCollection/DatasetCollection.vue @@ -0,0 +1,57 @@ + + + diff --git a/client/src/components/History/ContentItem/DatasetCollection/DscMenu.vue b/client/src/components/History/ContentItem/DatasetCollection/DscMenu.vue index 6a52cc1a6e1..fbe90484749 100644 --- a/client/src/components/History/ContentItem/DatasetCollection/DscMenu.vue +++ b/client/src/components/History/ContentItem/DatasetCollection/DscMenu.vue @@ -5,13 +5,13 @@ Delete Collection - Delete Collection Only + Delete Collection Only - + Delete Contained Datasets - + Purge Contained Datasets diff --git a/client/src/components/History/ContentItem/DatasetCollection/DscUI.vue b/client/src/components/History/ContentItem/DatasetCollection/DscUI.vue index 57a6cd1966b..25393e98d18 100644 --- a/client/src/components/History/ContentItem/DatasetCollection/DscUI.vue +++ b/client/src/components/History/ContentItem/DatasetCollection/DscUI.vue @@ -6,12 +6,9 @@ class="dataset dataset-collection collapsed" :class="{ selected }" :data-state="dsc.state" - @keydown.arrow-right.self.stop="$emit('select-collection', dsc)" + @keydown.arrow-right.self.stop="$emit('viewCollection')" @keydown.space.self.stop.prevent="$emit('update:selected', !selected)" - @click.stop=" - $emit('select-collection', dsc); - $emit('update:expanded', dsc); - " + @click.stop="$emit('viewCollection')" > + +
+ +
+ -
No summary
@@ -71,27 +75,20 @@ import { DatasetCollection } from "../../model/DatasetCollection"; import { StatusIcon, StateBtn } from "../../StatusIcon"; import JobStateProgress from "./JobStateProgress"; import DscMenu from "./DscMenu"; +import { Nametag } from "components/Nametags"; export default { - inject: ["listState", "STATES"], components: { StatusIcon, StateBtn, JobStateProgress, DscMenu, + Nametag, }, props: { dsc: { type: DatasetCollection, required: true }, selected: { type: Boolean, required: false, default: false }, - showHid: { type: Boolean, required: false, default: true }, - }, - computed: { - counter() { - return this.showHid ? this.dsc.hid : ""; - }, - showSelection() { - return this.listState.showSelection; - }, + showSelection: { type: Boolean, required: false, default: false }, }, methods: { onStatusClick() { diff --git a/client/src/components/History/ContentItem/DatasetCollection/index.js b/client/src/components/History/ContentItem/DatasetCollection/index.js new file mode 100644 index 00000000000..4d7f796c22b --- /dev/null +++ b/client/src/components/History/ContentItem/DatasetCollection/index.js @@ -0,0 +1,6 @@ +import DatasetCollection from "./DatasetCollection"; + +export { default as DscUI } from "./DscUI"; +export { default as DscMenu } from "./DscMenu"; +export { default as JobStateProgress } from "./JobStateProgress"; +export default DatasetCollection; diff --git a/client/src/components/History/ContentItem/DatasetCollection/index.vue b/client/src/components/History/ContentItem/DatasetCollection/index.vue deleted file mode 100644 index 49d4758c5d3..00000000000 --- a/client/src/components/History/ContentItem/DatasetCollection/index.vue +++ /dev/null @@ -1,67 +0,0 @@ - - - diff --git a/client/src/components/History/ContentItem/HistoryContentItem.js b/client/src/components/History/ContentItem/HistoryContentItem.js index fe65f664934..c6d8c6632dc 100644 --- a/client/src/components/History/ContentItem/HistoryContentItem.js +++ b/client/src/components/History/ContentItem/HistoryContentItem.js @@ -7,10 +7,6 @@ export default { contentItemComponent() { if (this.item.id === undefined) { return "Placeholder"; - // return "Loading"; - } - if (this.scrolling) { - return "Placeholder"; } const { history_content_type } = this.item; switch (history_content_type) { diff --git a/client/src/components/History/ContentItem/Subcollection.vue b/client/src/components/History/ContentItem/Subcollection.vue index fbef360ddfe..d17a8f6b5a0 100644 --- a/client/src/components/History/ContentItem/Subcollection.vue +++ b/client/src/components/History/ContentItem/Subcollection.vue @@ -7,12 +7,10 @@ v-on="$listeners" class="collapsed" :data-state="state" - @keydown.arrow-right.self.stop.prevent="$emit('select-collection', dsc)" + @keydown.arrow-right.self.stop.prevent="$emit('viewCollection')" + @click.stop="$emit('viewCollection')" > -