From ab3d53c5ce170855d68c955f5cb453d70989f630 Mon Sep 17 00:00:00 2001 From: John Chilton Date: Thu, 1 Feb 2018 23:20:16 -0500 Subject: [PATCH 1/5] More options for collection deletion. Delete button now a drop down menu (like dropdown for downloading metadata files). - Top option just deletes the collection. - Second option deletes the collection and attempts to delete the datasets contained within it. - The third option deletes the collection and attempts to purge the datasets within it. --- .../mvc/collection/collection-model.js | 14 +++-- .../scripts/mvc/history/hdca-li-edit.js | 57 ++++++++++++++----- lib/galaxy/managers/collections.py | 12 +++- .../webapps/galaxy/api/history_contents.py | 19 +++++-- 4 files changed, 79 insertions(+), 23 deletions(-) diff --git a/client/galaxy/scripts/mvc/collection/collection-model.js b/client/galaxy/scripts/mvc/collection/collection-model.js index 3b4fe0a8017..1550000e94f 100644 --- a/client/galaxy/scripts/mvc/collection/collection-model.js +++ b/client/galaxy/scripts/mvc/collection/collection-model.js @@ -1,5 +1,6 @@ import DATASET_MODEL from "mvc/dataset/dataset-model"; import BASE_MVC from "mvc/base-mvc"; +import Utils from "utils/utils"; import _l from "utils/localization"; //============================================================================== @@ -280,16 +281,19 @@ var DatasetCollection = Backbone.Model.extend(BASE_MVC.LoggableMixin) return parsed; }, - /** save this dataset, _Mark_ing it as deleted (just a flag) */ - delete: function(options) { + /** save this collection, _Mark_ing it as deleted (just a flag) */ + delete: function(recursive, purge, options) { + recursive = recursive || false; + purge = purge || false; if (this.get("deleted")) { return jQuery.when(); } - return this.save({ deleted: true }, options); + options = Utils.merge(options, {"method": "delete"}); + return this.save({ deleted: true, recursive: recursive, purge: purge }, options); }, - /** save this dataset, _Mark_ing it as undeleted */ + /** save this collection, _Mark_ing it as undeleted */ undelete: function(options) { - if (!this.get("deleted") || this.get("purged")) { + if (!this.get("deleted")) { return jQuery.when(); } return this.save({ deleted: false }, options); diff --git a/client/galaxy/scripts/mvc/history/hdca-li-edit.js b/client/galaxy/scripts/mvc/history/hdca-li-edit.js index db96ef88def..99130e48592 100644 --- a/client/galaxy/scripts/mvc/history/hdca-li-edit.js +++ b/client/galaxy/scripts/mvc/history/hdca-li-edit.js @@ -11,6 +11,13 @@ var HDCAListItemEdit = _super.extend( /** @lends HDCAListItemEdit.prototype */ { /** logger used to record this.log messages, commonly set to console */ //logger : console, + /** set up: options */ + initialize: function(attributes) { + _super.prototype.initialize.call(this, attributes); + + /** allow user purge of dataset files? */ + this.purgeAllowed = attributes.purgeAllowed || false; + }, /** Override to return editable versions of the collection panels */ _getFoldoutPanelClass: function() { @@ -25,22 +32,46 @@ var HDCAListItemEdit = _super.extend( return _super.prototype._renderPrimaryActions.call(this).concat([this._renderDeleteButton()]); }, - /** Render icon-button to delete this collection. */ _renderDeleteButton: function() { - var deleted = this.model.get("deleted"); - return faIconButton({ - title: deleted ? _l("Dataset collection is already deleted") : _l("Delete"), - classes: "delete-btn", - faIcon: "fa-times", - disabled: deleted, - onclick: () => { - // ...bler... tooltips being left behind in DOM (hover out never called on deletion) - this.$el.find(".icon-btn.delete-btn").trigger("mouseout"); - this.model["delete"](); - } - }); + return $(` + `); }, + + // ......................................................................... misc + events: _.extend(_.clone(_super.prototype.events), { + "click .delete-collection": function(ev) { + this.model["delete"](); + }, + "click .delete-collection-and-datasets": function(ev) { + this.model["delete"](true); + }, + "click .delete-collection-and-purge-datasets": function(ev) { + this.model["delete"](true, true); + } + }), + // ......................................................................... misc /** string rep */ toString: function() { diff --git a/lib/galaxy/managers/collections.py b/lib/galaxy/managers/collections.py index e823b0f44ca..fe688abad53 100644 --- a/lib/galaxy/managers/collections.py +++ b/lib/galaxy/managers/collections.py @@ -215,10 +215,20 @@ class DatasetCollectionManager(object): collection_type_description = self.collection_type_descriptions.for_collection_type(collection_type) return builder.BoundCollectionBuilder(dataset_collection, collection_type_description) - def delete(self, trans, instance_type, id): + def delete(self, trans, instance_type, id, recursive=False, purge=False): dataset_collection_instance = self.get_dataset_collection_instance(trans, instance_type, id, check_ownership=True) dataset_collection_instance.deleted = True trans.sa_session.add(dataset_collection_instance) + + if recursive: + for dataset in dataset_collection_instance.collection.dataset_instances: + self.hda_manager.error_unless_owner(dataset, user=trans.get_user(), current_history=trans.history) + if not dataset.deleted: + dataset.deleted = True + + if purge and not dataset.purged: + self.hda_manager.purge(dataset) + trans.sa_session.flush() def update(self, trans, instance_type, id, payload): diff --git a/lib/galaxy/webapps/galaxy/api/history_contents.py b/lib/galaxy/webapps/galaxy/api/history_contents.py index ef73f4fffe3..dc418e3472f 100644 --- a/lib/galaxy/webapps/galaxy/api/history_contents.py +++ b/lib/galaxy/webapps/galaxy/api/history_contents.py @@ -624,22 +624,26 @@ class HistoryContentsController(BaseAPIController, UsesLibraryMixin, UsesLibrary # TODO: allow anonymous del/purge and test security on this @expose_api - def delete(self, trans, history_id, id, purge=False, **kwd): + def delete(self, trans, history_id, id, purge=False, recursive=False, **kwd): """ delete( self, trans, history_id, id, **kwd ) * DELETE /api/histories/{history_id}/contents/{id} - delete the HDA with the given ``id`` + * DELETE /api/histories/{history_id}/contents/{type}s/{id} + delete the history content with the given ``id`` and specified type (defaults to dataset) .. note:: Currently does not stop any active jobs for which this dataset is an output. :type id: str :param id: the encoded id of the history to delete + :type recursive: bool + :param recursive: if True, and deleted an HDCA also delete containing HDAs :type purge: bool - :param purge: if True, purge the HDA + :param purge: if True, purge the target HDA or child HDAs of the target HDCA :type kwd: dict :param kwd: (optional) dictionary structure containing: * payload: a dictionary itself containing: * purge: if True, purge the HDA + * recursive: if True, see above. .. note:: that payload optionally can be placed in the query string of the request. This allows clients that strip the request body to still purge the dataset. @@ -654,7 +658,14 @@ class HistoryContentsController(BaseAPIController, UsesLibraryMixin, UsesLibrary if contents_type == "dataset": return self.__delete_dataset(trans, history_id, id, purge=purge, **kwd) elif contents_type == "dataset_collection": - trans.app.dataset_collections_service.delete(trans, "history", id) + purge = util.string_as_bool(purge) + recursive = util.string_as_bool(recursive) + if kwd.get('payload', None): + # payload takes priority + purge = util.string_as_bool(kwd['payload'].get('purge', purge)) + recursive = util.string_as_bool(kwd['payload'].get('recursive', recursive)) + + trans.app.dataset_collections_service.delete(trans, "history", id, recursive=recursive, purge=purge) return {'id' : id, "deleted": True} else: return self.__handle_unknown_contents_type(trans, contents_type) From 55b6d601a8ae5ad43a234721b2b21cc6db6ae067 Mon Sep 17 00:00:00 2001 From: Martin Cech Date: Fri, 2 Feb 2018 13:32:56 -0500 Subject: [PATCH 2/5] add empty href to links so the cursor is right --- client/galaxy/scripts/mvc/history/hdca-li-edit.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/galaxy/scripts/mvc/history/hdca-li-edit.js b/client/galaxy/scripts/mvc/history/hdca-li-edit.js index 99130e48592..dd55ae475bb 100644 --- a/client/galaxy/scripts/mvc/history/hdca-li-edit.js +++ b/client/galaxy/scripts/mvc/history/hdca-li-edit.js @@ -40,17 +40,17 @@ var HDCAListItemEdit = _super.extend( From 3512096a146f7d32ebc352049717df22a7c87fef Mon Sep 17 00:00:00 2001 From: Martin Cech Date: Fri, 2 Feb 2018 13:53:26 -0500 Subject: [PATCH 4/5] remove unused classes and aria --- client/galaxy/scripts/mvc/dataset/dataset-li.js | 2 +- client/galaxy/scripts/mvc/history/hdca-li-edit.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/galaxy/scripts/mvc/dataset/dataset-li.js b/client/galaxy/scripts/mvc/dataset/dataset-li.js index e1b54b1d0ce..ff9a6a1cf0d 100644 --- a/client/galaxy/scripts/mvc/dataset/dataset-li.js +++ b/client/galaxy/scripts/mvc/dataset/dataset-li.js @@ -302,7 +302,7 @@ var DatasetListItemView = _super.extend( )}"> -