Merge pull request #5038 from jmchilton/unwind_collection_client

Render arbitrarily nested lists in the UI
This commit is contained in:
Martin Cech
2017-11-30 14:15:20 -05:00
committed by GitHub
30 changed files with 306 additions and 468 deletions
@@ -90,7 +90,10 @@ var DatasetCollectionElement = Backbone.Model.extend(BASE_MVC.LoggableMixin)
.extend({ _logNamespace: "collections" });
//==============================================================================
/** @class Base/Abstract Backbone collection for Generic DCEs. */
/** @class Base/Abstract Backbone collection for Generic DCEs -
current may be associated with a dataset (DatasetDCECollection)
or another collection (NestedDCDCECollection).
*/
var DCECollection = Backbone.Collection.extend(BASE_MVC.LoggableMixin).extend(
/** @lends DCECollection.prototype */ {
_logNamespace: "collections",
@@ -197,7 +200,13 @@ var DatasetCollection = Backbone.Model.extend(BASE_MVC.LoggableMixin)
},
/** Which class to use for elements */
collectionClass: DCECollection,
collectionClass: function() {
if (this.attributes.collection_type.indexOf(":") > 0) {
return NestedDCDCECollection;
} else {
return DatasetDCECollection;
}
},
/** set up: create elements instance var and (on changes to elements) update them */
initialize: function(model, options) {
@@ -212,7 +221,8 @@ var DatasetCollection = Backbone.Model.extend(BASE_MVC.LoggableMixin)
/** move elements model attribute to full collection */
_createElementsModel: function() {
this.debug(`${this}._createElementsModel`, this.collectionClass, this.get("elements"), this.elements);
var collectionClass = this.collectionClass();
this.debug(`${this}._createElementsModel`, collectionClass, this.get("elements"), this.elements);
//TODO: same patterns as DatasetCollectionElement _createObjectModel - refactor to BASE_MVC.hasSubModel?
var elements = this.get("elements") || [];
this.unset("elements", { silent: true });
@@ -222,7 +232,7 @@ var DatasetCollection = Backbone.Model.extend(BASE_MVC.LoggableMixin)
parent_hdca_id: self.get("id")
});
});
this.elements = new this.collectionClass(elements);
this.elements = new collectionClass(elements);
//this.debug( 'collectionClass:', this.collectionClass + '', this.elements );
return this.elements;
},
@@ -303,39 +313,12 @@ var DatasetCollection = Backbone.Model.extend(BASE_MVC.LoggableMixin)
}
);
//==============================================================================
/** Model for a DatasetCollection containing datasets (non-nested).
*/
var ListDatasetCollection = DatasetCollection.extend(
/** @lends ListDatasetCollection.prototype */ {
/** override since we know the collection will only contain datasets */
collectionClass: DatasetDCECollection,
/** String representation. */
toString: function() {
return `List${DatasetCollection.prototype.toString.call(this)}`;
}
}
);
//==============================================================================
/** Model for a DatasetCollection containing fwd/rev datasets (a list of 2).
*/
var PairDatasetCollection = ListDatasetCollection.extend(
/** @lends PairDatasetCollection.prototype */ {
/** String representation. */
toString: function() {
return `Pair${DatasetCollection.prototype.toString.call(this)}`;
}
}
);
//_________________________________________________________________________________________________ NESTED COLLECTIONS
// this is where things get weird, man. Weird.
//TODO: it might be possible to compact all the following...I think.
//==============================================================================
/** @class Backbone model for a Generic DatasetCollectionElement that is also a DatasetCollection
* (a nested collection). Currently only list:paired.
* (a nested collection).
*/
var NestedDCDCE = DatasetCollection.extend(
BASE_MVC.mixin(
@@ -374,113 +357,7 @@ var NestedDCDCECollection = DCECollection.extend(
}
);
//==============================================================================
/** @class Backbone model for a paired dataset collection within a list:paired dataset collection.
*/
var NestedPairDCDCE = PairDatasetCollection.extend(
BASE_MVC.mixin(
DatasetCollectionElementMixin,
/** @lends NestedPairDCDCE.prototype */ {
//TODO:?? possibly rename to NestedDatasetCollection?
// because all objects have constructors (as this hashmap would even if this next line wasn't present)
// the constructor in hcontentMixin won't be attached by BASE_MVC.mixin to this model
// - re-apply manually it now
/** This is both a collection and a collection element - call the constructor */
constructor: function(attributes, options) {
this.debug("\t NestedPairDCDCE.constructor:", attributes, options);
//DatasetCollection.constructor.call( this, attributes, options );
DatasetCollectionElementMixin.constructor.call(this, attributes, options);
},
/** String representation. */
toString: function() {
var objStr = this.object ? `${this.object}` : this.get("element_identifier");
return ["NestedPairDCDCE(", objStr, ")"].join("");
}
}
)
);
//==============================================================================
/** @class Backbone collection for a backbone collection containing paired dataset collections.
*/
var NestedPairDCDCECollection = NestedDCDCECollection.extend(
/** @lends PairDCDCECollection.prototype */ {
/** We know this collection is composed of only nested pair collections */
model: NestedPairDCDCE,
/** String representation. */
toString: function() {
return ["NestedPairDCDCECollection(", this.length, ")"].join("");
}
}
);
//==============================================================================
/** @class Backbone Model for a DatasetCollection (list) that contains DatasetCollections (pairs).
*/
var ListPairedDatasetCollection = DatasetCollection.extend(
/** @lends ListPairedDatasetCollection.prototype */ {
/** list:paired is the only collection that itself contains collections */
collectionClass: NestedPairDCDCECollection,
/** String representation. */
toString: function() {
return ["ListPairedDatasetCollection(", this.get("name"), ")"].join("");
}
}
);
//==============================================================================
/** @class Backbone model for a list dataset collection within a list:list dataset collection. */
var NestedListDCDCE = ListDatasetCollection.extend(
BASE_MVC.mixin(
DatasetCollectionElementMixin,
/** @lends NestedListDCDCE.prototype */ {
/** This is both a collection and a collection element - call the constructor */
constructor: function(attributes, options) {
this.debug("\t NestedListDCDCE.constructor:", attributes, options);
DatasetCollectionElementMixin.constructor.call(this, attributes, options);
},
/** String representation. */
toString: function() {
var objStr = this.object ? `${this.object}` : this.get("element_identifier");
return ["NestedListDCDCE(", objStr, ")"].join("");
}
}
)
);
//==============================================================================
/** @class Backbone collection containing list dataset collections. */
var NestedListDCDCECollection = NestedDCDCECollection.extend({
/** We know this collection is composed of only nested pair collections */
model: NestedListDCDCE,
/** String representation. */
toString: function() {
return ["NestedListDCDCECollection(", this.length, ")"].join("");
}
});
//==============================================================================
/** @class Backbone Model for a DatasetCollection (list) that contains other lists. */
var ListOfListsDatasetCollection = DatasetCollection.extend({
/** list:paired is the only collection that itself contains collections */
collectionClass: NestedListDCDCECollection,
/** String representation. */
toString: function() {
return ["ListOfListsDatasetCollection(", this.get("name"), ")"].join("");
}
});
//==============================================================================
export default {
ListDatasetCollection: ListDatasetCollection,
PairDatasetCollection: PairDatasetCollection,
ListPairedDatasetCollection: ListPairedDatasetCollection,
ListOfListsDatasetCollection: ListOfListsDatasetCollection
DatasetCollection: DatasetCollection
};
@@ -26,6 +26,12 @@ var CollectionViewEdit = _super.extend(
/** sub view class used for nested collections */
NestedDCDCEViewClass: DC_EDIT.NestedDCDCEListItemEdit,
getNestedDCDCEViewClass: function() {
return DC_EDIT.NestedDCDCEListItemEdit.extend({
foldoutPanelClass: CollectionViewEdit
});
},
// ......................................................................... SET UP
/** Set up the view, set up storage, bind listeners to HistoryContents events
* @param {Object} attributes optional settings for the panel
@@ -90,94 +96,7 @@ var CollectionViewEdit = _super.extend(
}
);
// =============================================================================
/** @class non-editable, read-only View/Controller for a dataset collection. */
var ListCollectionViewEdit = CollectionViewEdit.extend(
/** @lends ListCollectionView.prototype */ {
//TODO: not strictly needed - due to switch in CollectionView._getContentClass
/** sub view class used for datasets */
DatasetDCEViewClass: DC_EDIT.DatasetDCEListItemEdit,
// ........................................................................ misc
/** string rep */
toString: function() {
return `ListCollectionViewEdit(${this.model ? this.model.get("name") : ""})`;
}
}
);
// =============================================================================
/** @class Editable, read-only View/Controller for a dataset collection. */
var PairCollectionViewEdit = ListCollectionViewEdit.extend(
/** @lends PairCollectionViewEdit.prototype */ {
// ........................................................................ misc
/** string rep */
toString: function() {
return `PairCollectionViewEdit(${this.model ? this.model.get("name") : ""})`;
}
}
);
// =============================================================================
/** @class Editable (roughly since these collections are immutable),
* View/Controller for a dataset collection.
*/
var NestedPairCollectionViewEdit = PairCollectionViewEdit.extend(
/** @lends NestedPairCollectionViewEdit.prototype */ {
/** Override to remove the editable text from the name/identifier - these collections are considered immutable */
_setUpBehaviors: function($where) {
_super.prototype._setUpBehaviors.call(this, $where);
},
// ........................................................................ misc
/** string rep */
toString: function() {
return `NestedPairCollectionViewEdit(${this.model ? this.model.get("name") : ""})`;
}
}
);
// =============================================================================
/** @class editable, View/Controller for a list of pairs dataset collection. */
var ListOfPairsCollectionViewEdit = CollectionViewEdit.extend(
/** @lends ListOfPairsCollectionView.prototype */ {
//TODO: not strictly needed - due to switch in CollectionView._getContentClass
/** sub view class used for nested collections */
NestedDCDCEViewClass: DC_EDIT.NestedDCDCEListItemEdit.extend({
foldoutPanelClass: NestedPairCollectionViewEdit
}),
// ........................................................................ misc
/** string rep */
toString: function() {
return `ListOfPairsCollectionViewEdit(${this.model ? this.model.get("name") : ""})`;
}
}
);
// =============================================================================
/** @class View/Controller for a list of lists dataset collection. */
var ListOfListsCollectionViewEdit = CollectionViewEdit.extend(
/** @lends ListOfListsCollectionView.prototype */ {
//TODO: not strictly needed - due to switch in CollectionView._getContentClass
/** sub view class used for nested collections */
NestedDCDCEViewClass: DC_EDIT.NestedDCDCEListItemEdit.extend({
foldoutPanelClass: NestedPairCollectionViewEdit
}),
// ........................................................................ misc
/** string rep */
toString: function() {
return `ListOfListsCollectionViewEdit(${this.model ? this.model.get("name") : ""})`;
}
}
);
//==============================================================================
export default {
CollectionViewEdit: CollectionViewEdit,
ListCollectionViewEdit: ListCollectionViewEdit,
PairCollectionViewEdit: PairCollectionViewEdit,
ListOfPairsCollectionViewEdit: ListOfPairsCollectionViewEdit,
ListOfListsCollectionViewEdit: ListOfListsCollectionViewEdit
CollectionViewEdit: CollectionViewEdit
};
@@ -21,8 +21,7 @@ var CollectionView = _super.extend(
/** sub view class used for datasets */
DatasetDCEViewClass: DC_LI.DatasetDCEListItemView,
/** sub view class used for nested collections */
NestedDCDCEViewClass: DC_LI.NestedDCDCEListItemView,
/** key of attribute in model to assign to this.collection */
modelCollectionKey: "elements",
@@ -44,6 +43,12 @@ var CollectionView = _super.extend(
this.downloadUrl = `${Galaxy.root}api/dataset_collections/${this.model.attributes.id}/download`;
},
getNestedDCDCEViewClass: function() {
return DC_LI.NestedDCDCEListItemView.extend({
foldoutPanelClass: CollectionView
});
},
_queueNewRender: function($newRender, speed) {
speed = speed === undefined ? this.fxSpeed : speed;
var panel = this;
@@ -71,7 +76,7 @@ var CollectionView = _super.extend(
case "hda":
return this.DatasetDCEViewClass;
case "dataset_collection":
return this.NestedDCDCEViewClass;
return this.getNestedDCDCEViewClass();
}
throw new TypeError("Unknown element type:", model.get("element_type"));
},
@@ -189,71 +194,7 @@ CollectionView.prototype.templates = (() => {
});
})();
// =============================================================================
/** @class non-editable, read-only View/Controller for a dataset collection. */
var ListCollectionView = CollectionView.extend(
/** @lends ListCollectionView.prototype */ {
//TODO: not strictly needed - due to switch in CollectionView._getContentClass
/** sub view class used for datasets */
DatasetDCEViewClass: DC_LI.DatasetDCEListItemView,
// ........................................................................ misc
/** string rep */
toString: function() {
return `ListCollectionView(${this.model ? this.model.get("name") : ""})`;
}
}
);
// =============================================================================
/** @class non-editable, read-only View/Controller for a dataset collection. */
var PairCollectionView = ListCollectionView.extend(
/** @lends PairCollectionView.prototype */ {
// ........................................................................ misc
/** string rep */
toString: function() {
return `PairCollectionView(${this.model ? this.model.get("name") : ""})`;
}
}
);
// =============================================================================
/** @class non-editable, read-only View/Controller for a dataset collection. */
var ListOfPairsCollectionView = CollectionView.extend(
/** @lends ListOfPairsCollectionView.prototype */ {
//TODO: not strictly needed - due to switch in CollectionView._getContentClass
/** sub view class used for nested collections */
NestedDCDCEViewClass: DC_LI.NestedDCDCEListItemView.extend({
foldoutPanelClass: PairCollectionView
}),
// ........................................................................ misc
/** string rep */
toString: function() {
return `ListOfPairsCollectionView(${this.model ? this.model.get("name") : ""})`;
}
}
);
// =============================================================================
/** @class non-editable, read-only View/Controller for a list of lists dataset collection. */
var ListOfListsCollectionView = CollectionView.extend({
/** sub view class used for nested collections */
NestedDCDCEViewClass: DC_LI.NestedDCDCEListItemView.extend({
foldoutPanelClass: PairCollectionView
}),
/** string rep */
toString: function() {
return `ListOfListsCollectionView(${this.model ? this.model.get("name") : ""})`;
}
});
//==============================================================================
export default {
CollectionView: CollectionView,
ListCollectionView: ListCollectionView,
PairCollectionView: PairCollectionView,
ListOfPairsCollectionView: ListOfPairsCollectionView,
ListOfListsCollectionView: ListOfListsCollectionView
CollectionView: CollectionView
};
@@ -173,7 +173,7 @@ var ListCollectionCreator = Backbone.View.extend(BASE_MVC.LoggableMixin)
/** the class used to display individual elements */
elementViewClass: DatasetCollectionElementView,
/** the class this creator will create and save */
collectionClass: HDCA.HistoryListDatasetCollection,
collectionClass: HDCA.HistoryDatasetCollection,
className: "list-collection-creator collection-creator flex-row-container",
/** minimum number of valid elements to start with in order to build a collection of this type */
@@ -623,7 +623,6 @@ var PairedCollectionCreator = Backbone.View.extend(baseMVC.LoggableMixin)
var url = `${Galaxy.root}api/histories/${this.historyId}/contents/dataset_collections`;
//TODO: use ListPairedCollection.create()
var ajaxData = {
type: "dataset_collection",
collection_type: "list:paired",
@@ -61,7 +61,7 @@ var PairCollectionCreator = _super.extend({
/** the class used to display individual elements */
elementViewClass: PairedDatasetCollectionElementView,
/** the class this creator will create and save */
collectionClass: HDCA.HistoryPairDatasetCollection,
collectionClass: HDCA.HistoryDatasetCollection,
className: "pair-collection-creator collection-creator flex-row-container",
/** override to no-op */
@@ -66,7 +66,7 @@ var View = Backbone.View.extend({
message: response.message,
status: "success",
persistent: false
}
};
}
if (self.redirect) {
window.location = `${Galaxy.root + self.redirect}?${$.param(params)}`;
@@ -14,18 +14,7 @@ var HDCAListItemEdit = _super.extend(
/** Override to return editable versions of the collection panels */
_getFoldoutPanelClass: function() {
var collectionType = this.model.get("collection_type");
switch (collectionType) {
case "list":
return DC_VIEW_EDIT.ListCollectionViewEdit;
case "paired":
return DC_VIEW_EDIT.PairCollectionViewEdit;
case "list:paired":
return DC_VIEW_EDIT.ListOfPairsCollectionViewEdit;
case "list:list":
return DC_VIEW_EDIT.ListOfListsCollectionViewEdit;
}
throw new TypeError(`Unknown collection_type: ${collectionType}`);
return DC_VIEW_EDIT.CollectionViewEdit;
},
// ......................................................................... delete
+1 -12
View File
@@ -29,18 +29,7 @@ var HDCAListItemView = _super.extend(
/** Override to provide the proper collections panels as the foldout */
_getFoldoutPanelClass: function() {
var collectionType = this.model.get("collection_type");
switch (collectionType) {
case "list":
return DC_VIEW.ListCollectionView;
case "paired":
return DC_VIEW.PairCollectionView;
case "list:paired":
return DC_VIEW.ListOfPairsCollectionView;
case "list:list":
return DC_VIEW.ListOfListsCollectionView;
}
throw new TypeError(`Unknown collection_type: ${collectionType}`);
return DC_VIEW.CollectionView;
},
/** In this override, add the state as a class for use with state-based CSS */
+16 -90
View File
@@ -6,115 +6,41 @@ import _l from "utils/localization";
Models for DatasetCollections contained within a history.
TODO:
these might be compactable to one class if some duplication with
collection-model is used.
==============================================================================*/
var hcontentMixin = HISTORY_CONTENT.HistoryContentMixin;
var ListDC = DC_MODEL.ListDatasetCollection;
var PairDC = DC_MODEL.PairDatasetCollection;
var ListPairedDC = DC_MODEL.ListPairedDatasetCollection;
var ListOfListsDC = DC_MODEL.ListOfListsDatasetCollection;
//==============================================================================
/** Override to post to contents route w/o id. */
function buildHDCASave(_super) {
return function _save(attributes, options) {
if (this.isNew()) {
options = options || {};
options.url = `${this.urlRoot + this.get("history_id")}/contents`;
attributes = attributes || {};
attributes.type = "dataset_collection";
}
return _super.call(this, attributes, options);
};
}
var DC = DC_MODEL.DatasetCollection;
//==============================================================================
/** @class Backbone model for List Dataset Collection within a History.
*/
var HistoryListDatasetCollection = ListDC.extend(hcontentMixin).extend(
/** @lends HistoryListDatasetCollection.prototype */ {
defaults: _.extend(_.clone(ListDC.prototype.defaults), {
var HistoryDatasetCollection = DC.extend(hcontentMixin).extend(
/** @lends HistoryDatasetCollection.prototype */ {
defaults: _.extend(_.clone(DC.prototype.defaults), {
history_content_type: "dataset_collection",
collection_type: "list",
model_class: "HistoryDatasetCollectionAssociation"
}),
//==============================================================================
/** Override to post to contents route w/o id. */
save: buildHDCASave(ListDC.prototype.save),
save: function(attributes, options) {
if (this.isNew()) {
options = options || {};
options.url = `${this.urlRoot + this.get("history_id")}/contents`;
attributes = attributes || {};
attributes.type = "dataset_collection";
}
return DC.prototype.save.call(this, attributes, options);
},
/** String representation. */
toString: function() {
return `History${ListDC.prototype.toString.call(this)}`;
return `History${DC.prototype.toString.call(this)}`;
}
}
);
//==============================================================================
/** @class Backbone model for Pair Dataset Collection within a History.
* @constructs
*/
var HistoryPairDatasetCollection = PairDC.extend(hcontentMixin).extend(
/** @lends HistoryPairDatasetCollection.prototype */ {
defaults: _.extend(_.clone(PairDC.prototype.defaults), {
history_content_type: "dataset_collection",
collection_type: "paired",
model_class: "HistoryDatasetCollectionAssociation"
}),
/** Override to post to contents route w/o id. */
save: buildHDCASave(PairDC.prototype.save),
/** String representation. */
toString: function() {
return `History${PairDC.prototype.toString.call(this)}`;
}
}
);
//==============================================================================
/** @class Backbone model for List of Pairs Dataset Collection within a History. */
var HistoryListPairedDatasetCollection = ListPairedDC.extend(hcontentMixin).extend({
defaults: _.extend(_.clone(ListPairedDC.prototype.defaults), {
history_content_type: "dataset_collection",
collection_type: "list:paired",
model_class: "HistoryDatasetCollectionAssociation"
}),
/** Override to post to contents route w/o id. */
save: buildHDCASave(ListPairedDC.prototype.save),
/** String representation. */
toString: function() {
return `History${ListPairedDC.prototype.toString.call(this)}`;
}
});
//==============================================================================
/** @class Backbone model for List of Lists Dataset Collection within a History. */
var HistoryListOfListsDatasetCollection = ListOfListsDC.extend(hcontentMixin).extend({
defaults: _.extend(_.clone(ListOfListsDC.prototype.defaults), {
history_content_type: "dataset_collection",
collection_type: "list:list",
model_class: "HistoryDatasetCollectionAssociation"
}),
/** Override to post to contents route w/o id. */
save: buildHDCASave(ListOfListsDC.prototype.save),
/** String representation. */
toString: function() {
return `HistoryListOfListsDatasetCollection(${this.get("name")})`;
}
});
//==============================================================================
export default {
HistoryListDatasetCollection: HistoryListDatasetCollection,
HistoryPairDatasetCollection: HistoryPairDatasetCollection,
HistoryListPairedDatasetCollection: HistoryListPairedDatasetCollection,
HistoryListOfListsDatasetCollection: HistoryListOfListsDatasetCollection
HistoryDatasetCollection: HistoryDatasetCollection
};
@@ -87,27 +87,12 @@ var HistoryContents = _super.extend(BASE_MVC.LoggableMixin).extend({
if (attrs.history_content_type === "dataset") {
return new HDA_MODEL.HistoryDatasetAssociation(attrs, options);
} else if (attrs.history_content_type === "dataset_collection") {
switch (attrs.collection_type) {
case "list":
return new HDCA_MODEL.HistoryListDatasetCollection(attrs, options);
case "paired":
return new HDCA_MODEL.HistoryPairDatasetCollection(attrs, options);
case "list:paired":
return new HDCA_MODEL.HistoryListPairedDatasetCollection(attrs, options);
case "list:list":
return new HDCA_MODEL.HistoryListOfListsDatasetCollection(attrs, options);
}
// This is a hack inside a hack:
// Raise a plain object with validationError to fake a model.validationError
// (since we don't have a model to use validate with)
// (the outer hack being the mixed content/model function in this collection)
var msg = `Unknown collection_type: ${attrs.collection_type}`;
console.warn(msg, attrs);
return { validationError: msg };
return new HDCA_MODEL.HistoryDatasetCollection(attrs, options);
} else {
return {
validationError: `Unknown history_content_type: ${attrs.history_content_type}`
};
}
return {
validationError: `Unknown history_content_type: ${attrs.history_content_type}`
};
},
stopPolling: function() {
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
define("mvc/collection/collection-view-edit",["exports","mvc/collection/collection-view","mvc/collection/collection-model","mvc/collection/collection-li-edit","mvc/base-mvc","mvc/tag","ui/fa-icon-button","utils/localization","ui/editable-text"],function(t,e,i,o,l,n,s,a){"use strict";function d(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(t,"__esModule",{value:!0});var c=d(e),r=(d(i),d(o)),m=(d(l),d(n)),u=(d(s),d(a)),f=c.default.CollectionView,C=f.extend({DatasetDCEViewClass:r.default.DatasetDCEListItemEdit,NestedDCDCEViewClass:r.default.NestedDCDCEListItemEdit,initialize:function(t){f.prototype.initialize.call(this,t)},_setUpBehaviors:function(t){if(t=t||this.$el,f.prototype._setUpBehaviors.call(this,t),this.model&&Galaxy.user&&!Galaxy.user.isAnonymous()){this.tagsEditorShown=!0;var e=this;t.find("> .controls .name").attr("title",(0,u.default)("Click to rename collection")).tooltip({placement:"bottom"}).make_text_editable({on_finish:function(t){var i=e.model.get("name");t&&t!==i?(e.$el.find("> .controls .name").text(t),e.model.save({name:t}).fail(function(){e.$el.find("> .controls .name").text(e.model.previous("name"))})):e.$el.find("> .controls .name").text(i)}}),this.tagsEditor=new m.default.TagsEditor({model:this.model,el:t.find(".tags-display"),onshowFirstTime:function(){this.render()},usePrompt:!1}),this.tagsEditor.toggle(!0)}},toString:function(){return"CollectionViewEdit("+(this.model?this.model.get("name"):"")+")"}}),h=C.extend({DatasetDCEViewClass:r.default.DatasetDCEListItemEdit,toString:function(){return"ListCollectionViewEdit("+(this.model?this.model.get("name"):"")+")"}}),E=h.extend({toString:function(){return"PairCollectionViewEdit("+(this.model?this.model.get("name"):"")+")"}}),w=E.extend({_setUpBehaviors:function(t){f.prototype._setUpBehaviors.call(this,t)},toString:function(){return"NestedPairCollectionViewEdit("+(this.model?this.model.get("name"):"")+")"}}),g=C.extend({NestedDCDCEViewClass:r.default.NestedDCDCEListItemEdit.extend({foldoutPanelClass:w}),toString:function(){return"ListOfPairsCollectionViewEdit("+(this.model?this.model.get("name"):"")+")"}}),D=C.extend({NestedDCDCEViewClass:r.default.NestedDCDCEListItemEdit.extend({foldoutPanelClass:w}),toString:function(){return"ListOfListsCollectionViewEdit("+(this.model?this.model.get("name"):"")+")"}});t.default={CollectionViewEdit:C,ListCollectionViewEdit:h,PairCollectionViewEdit:E,ListOfPairsCollectionViewEdit:g,ListOfListsCollectionViewEdit:D}});
define("mvc/collection/collection-view-edit",["exports","mvc/collection/collection-view","mvc/collection/collection-model","mvc/collection/collection-li-edit","mvc/base-mvc","mvc/tag","ui/fa-icon-button","utils/localization","ui/editable-text"],function(t,e,i,o,l,n,s,a){"use strict";function c(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(t,"__esModule",{value:!0});var d=c(e),r=(c(i),c(o)),m=(c(l),c(n)),u=(c(s),c(a)),f=d.default.CollectionView,C=f.extend({DatasetDCEViewClass:r.default.DatasetDCEListItemEdit,NestedDCDCEViewClass:r.default.NestedDCDCEListItemEdit,getNestedDCDCEViewClass:function(){return r.default.NestedDCDCEListItemEdit.extend({foldoutPanelClass:C})},initialize:function(t){f.prototype.initialize.call(this,t)},_setUpBehaviors:function(t){if(t=t||this.$el,f.prototype._setUpBehaviors.call(this,t),this.model&&Galaxy.user&&!Galaxy.user.isAnonymous()){this.tagsEditorShown=!0;var e=this;t.find("> .controls .name").attr("title",(0,u.default)("Click to rename collection")).tooltip({placement:"bottom"}).make_text_editable({on_finish:function(t){var i=e.model.get("name");t&&t!==i?(e.$el.find("> .controls .name").text(t),e.model.save({name:t}).fail(function(){e.$el.find("> .controls .name").text(e.model.previous("name"))})):e.$el.find("> .controls .name").text(i)}}),this.tagsEditor=new m.default.TagsEditor({model:this.model,el:t.find(".tags-display"),onshowFirstTime:function(){this.render()},usePrompt:!1}),this.tagsEditor.toggle(!0)}},toString:function(){return"CollectionViewEdit("+(this.model?this.model.get("name"):"")+")"}});t.default={CollectionViewEdit:C}});
@@ -1 +1 @@
define("mvc/collection/collection-view",["exports","mvc/list/list-view","mvc/collection/collection-model","mvc/collection/collection-li","mvc/base-mvc","utils/localization"],function(e,t,i,l,o,s){"use strict";function n(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(e,"__esModule",{value:!0});var a=n(t),c=(n(i),n(l)),d=n(o),r=n(s),f=a.default.ModelListPanel,p=f.extend({_logNamespace:"collections",className:f.prototype.className+" dataset-collection-panel",DatasetDCEViewClass:c.default.DatasetDCEListItemView,NestedDCDCEViewClass:c.default.NestedDCDCEListItemView,modelCollectionKey:"elements",initialize:function(e){f.prototype.initialize.call(this,e),this.linkTarget=e.linkTarget||"_blank",this.hasUser=e.hasUser,this.panelStack=[],this.parentName=e.parentName,this.foldoutStyle=e.foldoutStyle||"foldout",this.downloadUrl=Galaxy.root+"api/dataset_collections/"+this.model.attributes.id+"/download"},_queueNewRender:function(e,t){t=void 0===t?this.fxSpeed:t;var i=this;i.log("_queueNewRender:",e,t),i._swapNewRender(e),i.trigger("rendered",i)},_filterCollection:function(){return this.model.getVisibleContents()},_getItemViewClass:function(e){switch(e.get("element_type")){case"hda":return this.DatasetDCEViewClass;case"dataset_collection":return this.NestedDCDCEViewClass}throw new TypeError("Unknown element type:",e.get("element_type"))},_getItemViewOptions:function(e){var t=f.prototype._getItemViewOptions.call(this,e);return _.extend(t,{linkTarget:this.linkTarget,hasUser:this.hasUser,foldoutStyle:this.foldoutStyle})},_setUpItemViewListeners:function(e){var t=this;return f.prototype._setUpItemViewListeners.call(t,e),t.listenTo(e,{"expanded:drilldown":function(e,t){this._expandDrilldownPanel(t)},"collapsed:drilldown":function(e,t){this._collapseDrilldownPanel(t)}}),this},_expandDrilldownPanel:function(e){this.panelStack.push(e),this.$("> .controls").add(this.$list()).hide(),e.parentName=this.model.get("name"),this.$el.append(e.render().$el)},_collapseDrilldownPanel:function(e){this.panelStack.pop(),this.render()},events:{"click .navigation .back":"close"},close:function(e){this.remove(),this.trigger("close")},toString:function(){return"CollectionView("+(this.model?this.model.get("name"):"")+")"}});p.prototype.templates=function(){var e=d.default.wrapTemplate(['<div class="controls">','<div class="navigation">','<a class="back" href="javascript:void(0)">','<span class="fa fa-icon fa-angle-left"></span>',(0,r.default)("Back to "),"<%- view.parentName %>","</a>","</div>",'<div class="title">','<div class="name"><%- collection.name || collection.element_identifier %></div>','<div class="subtitle">','<% if( collection.collection_type === "list" ){ %>',(0,r.default)("a list of datasets"),'<% } else if( collection.collection_type === "paired" ){ %>',(0,r.default)("a pair of datasets"),'<% } else if( collection.collection_type === "list:paired" ){ %>',(0,r.default)("a list of paired datasets"),'<% } else if( collection.collection_type === "list:list" ){ %>',(0,r.default)("a list of dataset lists"),"<% } %>","</div>","</div>",'<div class="tags-display"></div>','<div class="actions">','<a class="download-btn icon-btn" ','href="<%- view.downloadUrl %>','" title="" download="" data-original-title="Download Collection">','<span class="fa fa-floppy-o"></span>',"</a>","</div>","</div>"],"collection");return _.extend(_.clone(f.prototype.templates),{controls:e})}();var u=p.extend({DatasetDCEViewClass:c.default.DatasetDCEListItemView,toString:function(){return"ListCollectionView("+(this.model?this.model.get("name"):"")+")"}}),m=u.extend({toString:function(){return"PairCollectionView("+(this.model?this.model.get("name"):"")+")"}}),w=p.extend({NestedDCDCEViewClass:c.default.NestedDCDCEListItemView.extend({foldoutPanelClass:m}),toString:function(){return"ListOfPairsCollectionView("+(this.model?this.model.get("name"):"")+")"}}),h=p.extend({NestedDCDCEViewClass:c.default.NestedDCDCEListItemView.extend({foldoutPanelClass:m}),toString:function(){return"ListOfListsCollectionView("+(this.model?this.model.get("name"):"")+")"}});e.default={CollectionView:p,ListCollectionView:u,PairCollectionView:m,ListOfPairsCollectionView:w,ListOfListsCollectionView:h}});
define("mvc/collection/collection-view",["exports","mvc/list/list-view","mvc/collection/collection-model","mvc/collection/collection-li","mvc/base-mvc","utils/localization"],function(e,t,l,i,o,a){"use strict";function s(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(e,"__esModule",{value:!0});var n=s(t),c=(s(l),s(i)),d=s(o),r=s(a),p=n.default.ModelListPanel,f=p.extend({_logNamespace:"collections",className:p.prototype.className+" dataset-collection-panel",DatasetDCEViewClass:c.default.DatasetDCEListItemView,modelCollectionKey:"elements",initialize:function(e){p.prototype.initialize.call(this,e),this.linkTarget=e.linkTarget||"_blank",this.hasUser=e.hasUser,this.panelStack=[],this.parentName=e.parentName,this.foldoutStyle=e.foldoutStyle||"foldout",this.downloadUrl=Galaxy.root+"api/dataset_collections/"+this.model.attributes.id+"/download"},getNestedDCDCEViewClass:function(){return c.default.NestedDCDCEListItemView.extend({foldoutPanelClass:f})},_queueNewRender:function(e,t){t=void 0===t?this.fxSpeed:t;var l=this;l.log("_queueNewRender:",e,t),l._swapNewRender(e),l.trigger("rendered",l)},_filterCollection:function(){return this.model.getVisibleContents()},_getItemViewClass:function(e){switch(e.get("element_type")){case"hda":return this.DatasetDCEViewClass;case"dataset_collection":return this.getNestedDCDCEViewClass()}throw new TypeError("Unknown element type:",e.get("element_type"))},_getItemViewOptions:function(e){var t=p.prototype._getItemViewOptions.call(this,e);return _.extend(t,{linkTarget:this.linkTarget,hasUser:this.hasUser,foldoutStyle:this.foldoutStyle})},_setUpItemViewListeners:function(e){var t=this;return p.prototype._setUpItemViewListeners.call(t,e),t.listenTo(e,{"expanded:drilldown":function(e,t){this._expandDrilldownPanel(t)},"collapsed:drilldown":function(e,t){this._collapseDrilldownPanel(t)}}),this},_expandDrilldownPanel:function(e){this.panelStack.push(e),this.$("> .controls").add(this.$list()).hide(),e.parentName=this.model.get("name"),this.$el.append(e.render().$el)},_collapseDrilldownPanel:function(e){this.panelStack.pop(),this.render()},events:{"click .navigation .back":"close"},close:function(e){this.remove(),this.trigger("close")},toString:function(){return"CollectionView("+(this.model?this.model.get("name"):"")+")"}});f.prototype.templates=function(){var e=d.default.wrapTemplate(['<div class="controls">','<div class="navigation">','<a class="back" href="javascript:void(0)">','<span class="fa fa-icon fa-angle-left"></span>',(0,r.default)("Back to "),"<%- view.parentName %>","</a>","</div>",'<div class="title">','<div class="name"><%- collection.name || collection.element_identifier %></div>','<div class="subtitle">','<% if( collection.collection_type === "list" ){ %>',(0,r.default)("a list of datasets"),'<% } else if( collection.collection_type === "paired" ){ %>',(0,r.default)("a pair of datasets"),'<% } else if( collection.collection_type === "list:paired" ){ %>',(0,r.default)("a list of paired datasets"),'<% } else if( collection.collection_type === "list:list" ){ %>',(0,r.default)("a list of dataset lists"),"<% } %>","</div>","</div>",'<div class="tags-display"></div>','<div class="actions">','<a class="download-btn icon-btn" ','href="<%- view.downloadUrl %>','" title="" download="" data-original-title="Download Collection">','<span class="fa fa-floppy-o"></span>',"</a>","</div>","</div>"],"collection");return _.extend(_.clone(p.prototype.templates),{controls:e})}(),e.default={CollectionView:f}});
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
define("mvc/history/hdca-li-edit",["exports","mvc/history/hdca-li","mvc/collection/collection-view-edit","ui/fa-icon-button","utils/localization"],function(e,t,i,l,n){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(e,"__esModule",{value:!0});var r=o(t),d=o(i),s=o(l),c=o(n),a=r.default.HDCAListItemView,u=a.extend({_getFoldoutPanelClass:function(){var e=this.model.get("collection_type");switch(e){case"list":return d.default.ListCollectionViewEdit;case"paired":return d.default.PairCollectionViewEdit;case"list:paired":return d.default.ListOfPairsCollectionViewEdit;case"list:list":return d.default.ListOfListsCollectionViewEdit}throw new TypeError("Unknown collection_type: "+e)},_renderPrimaryActions:function(){return this.log(this+"._renderPrimaryActions"),a.prototype._renderPrimaryActions.call(this).concat([this._renderDeleteButton()])},_renderDeleteButton:function(){var e=this,t=this.model.get("deleted");return(0,s.default)({title:t?(0,c.default)("Dataset collection is already deleted"):(0,c.default)("Delete"),classes:"delete-btn",faIcon:"fa-times",disabled:t,onclick:function(){e.$el.find(".icon-btn.delete-btn").trigger("mouseout"),e.model.delete()}})},toString:function(){return"HDCAListItemEdit("+(this.model?""+this.model:"(no model)")+")"}});e.default={HDCAListItemEdit:u}});
define("mvc/history/hdca-li-edit",["exports","mvc/history/hdca-li","mvc/collection/collection-view-edit","ui/fa-icon-button","utils/localization"],function(e,t,i,n,l){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(e,"__esModule",{value:!0});var d=o(t),r=o(i),c=o(n),s=o(l),u=d.default.HDCAListItemView,a=u.extend({_getFoldoutPanelClass:function(){return r.default.CollectionViewEdit},_renderPrimaryActions:function(){return this.log(this+"._renderPrimaryActions"),u.prototype._renderPrimaryActions.call(this).concat([this._renderDeleteButton()])},_renderDeleteButton:function(){var e=this,t=this.model.get("deleted");return(0,c.default)({title:t?(0,s.default)("Dataset collection is already deleted"):(0,s.default)("Delete"),classes:"delete-btn",faIcon:"fa-times",disabled:t,onclick:function(){e.$el.find(".icon-btn.delete-btn").trigger("mouseout"),e.model.delete()}})},toString:function(){return"HDCAListItemEdit("+(this.model?""+this.model:"(no model)")+")"}});e.default={HDCAListItemEdit:a}});
+1 -1
View File
@@ -1 +1 @@
define("mvc/history/hdca-li",["exports","mvc/dataset/states","mvc/collection/collection-li","mvc/collection/collection-view","mvc/base-mvc","mvc/history/history-item-li","utils/localization"],function(e,t,s,i,n,a,r){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(e,"__esModule",{value:!0});var l=o(t),d=o(s),c=o(i),p=(o(n),o(a)),u=o(r),h=d.default.DCListItemView,m=h.extend({className:h.prototype.className+" history-content",_setUpListeners:function(){var e=this;h.prototype._setUpListeners.call(this);var t=function(t,s){e.render()};this.model.jobStatesSummary&&this.listenTo(this.model.jobStatesSummary,"change",t),this.listenTo(this.model,{"change:tags change:visible change:state":t})},_getFoldoutPanelClass:function(){var e=this.model.get("collection_type");switch(e){case"list":return c.default.ListCollectionView;case"paired":return c.default.PairCollectionView;case"list:paired":return c.default.ListOfPairsCollectionView;case"list:list":return c.default.ListOfListsCollectionView}throw new TypeError("Unknown collection_type: "+e)},_swapNewRender:function(e){h.prototype._swapNewRender.call(this,e);var t,s=this.model.jobStatesSummary;t=s?s.new()?"loading":s.errored()?"error":s.terminal()?"ok":s.running()?"running":"queued":this.model.get("job_source_id")?"loading":this.model.get("populated_state")?l.default.OK:l.default.RUNNING,this.$el.addClass("state-"+t);var i=this.stateDescription();return this.$(".state-description").html(i),this.$el},stateDescription:function(){var e,t=this.model,s=t.get("element_count"),i=t.get("job_source_type"),n=this.model.get("collection_type");e="list"==n?"list":"paired"==n?"dataset pair":"list:paired"==n?"list of pairs":"nested list";var a="";1==s?a=" with 1 item":s&&(a=" with "+s+" items");var r=t.jobStatesSummary,o=""+e+a;if(i&&"Job"!=i){if(r&&r.hasDetails()){var l=r.new(),d=l?null:r.jobCount();if(l)return'\n <div class="progress state-progress">\n <span class="note">Creating jobs.<span class="blinking">..</span></span>\n <div class="progress-bar info" style="width:100%">\n </div>';if(r.errored())return"a "+e+" with "+r.numInError()+" / "+d+" jobs in error";if(r.terminal())return"a "+o;var c=r.states().running||0,p=(r.states().ok||0)/(1*d),u=c/(1*d),h=1-p-u;return'\n <div class="progress state-progress">\n <span class="note">'+(d&&d>1?d+" jobs":"a job")+" generating a "+e+'</span>\n <div class="progress-bar ok" style="width:'+100*p+'%"></div>\n <div class="progress-bar running" style="width:'+100*u+'%"></div>\n <div class="progress-bar new" style="width:'+100*h+'%">\n </div>'}return'\n <div class="progress state-progress">\n <span class="note">Loading job data for '+e+'.<span class="blinking">..</span></span>\n <div class="progress-bar info" style="width:100%">\n </div>'}return"a "+o},toString:function(){return"HDCAListItemView("+(this.model?""+this.model:"(no model)")+")"}});m.prototype.templates=function(){var e=_.extend({},h.prototype.templates.warnings,{hidden:function(e){e.visible||(0,u.default)("This collection has been hidden")}});return _.extend({},h.prototype.templates,{warnings:e,titleBar:function(e){return'\n <div class="title-bar clear" tabindex="0">\n <span class="state-icon"></span>\n <div class="title">\n <span class="hid">'+e.hid+'</span>\n <span class="name">'+_.escape(e.name)+'</span>\n </div>\n <div class="state-description">\n </div>\n '+p.default.nametagTemplate(e)+"\n </div>\n "}})}(),e.default={HDCAListItemView:m}});
define("mvc/history/hdca-li",["exports","mvc/dataset/states","mvc/collection/collection-li","mvc/collection/collection-view","mvc/base-mvc","mvc/history/history-item-li","utils/localization"],function(t,e,s,n,i,a,r){"use strict";function o(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(t,"__esModule",{value:!0});var l=o(e),d=o(s),c=o(n),p=(o(i),o(a)),u=o(r),m=d.default.DCListItemView,h=m.extend({className:m.prototype.className+" history-content",_setUpListeners:function(){var t=this;m.prototype._setUpListeners.call(this);var e=function(e,s){t.render()};this.model.jobStatesSummary&&this.listenTo(this.model.jobStatesSummary,"change",e),this.listenTo(this.model,{"change:tags change:visible change:state":e})},_getFoldoutPanelClass:function(){return c.default.CollectionView},_swapNewRender:function(t){m.prototype._swapNewRender.call(this,t);var e,s=this.model.jobStatesSummary;e=s?s.new()?"loading":s.errored()?"error":s.terminal()?"ok":s.running()?"running":"queued":this.model.get("job_source_id")?"loading":this.model.get("populated_state")?l.default.OK:l.default.RUNNING,this.$el.addClass("state-"+e);var n=this.stateDescription();return this.$(".state-description").html(n),this.$el},stateDescription:function(){var t,e=this.model,s=e.get("element_count"),n=e.get("job_source_type"),i=this.model.get("collection_type");t="list"==i?"list":"paired"==i?"dataset pair":"list:paired"==i?"list of pairs":"nested list";var a="";1==s?a=" with 1 item":s&&(a=" with "+s+" items");var r=e.jobStatesSummary,o=""+t+a;if(n&&"Job"!=n){if(r&&r.hasDetails()){var l=r.new(),d=l?null:r.jobCount();if(l)return'\n <div class="progress state-progress">\n <span class="note">Creating jobs.<span class="blinking">..</span></span>\n <div class="progress-bar info" style="width:100%">\n </div>';if(r.errored())return"a "+t+" with "+r.numInError()+" / "+d+" jobs in error";if(r.terminal())return"a "+o;var c=r.states().running||0,p=(r.states().ok||0)/(1*d),u=c/(1*d),m=1-p-u;return'\n <div class="progress state-progress">\n <span class="note">'+(d&&d>1?d+" jobs":"a job")+" generating a "+t+'</span>\n <div class="progress-bar ok" style="width:'+100*p+'%"></div>\n <div class="progress-bar running" style="width:'+100*u+'%"></div>\n <div class="progress-bar new" style="width:'+100*m+'%">\n </div>'}return'\n <div class="progress state-progress">\n <span class="note">Loading job data for '+t+'.<span class="blinking">..</span></span>\n <div class="progress-bar info" style="width:100%">\n </div>'}return"a "+o},toString:function(){return"HDCAListItemView("+(this.model?""+this.model:"(no model)")+")"}});h.prototype.templates=function(){var t=_.extend({},m.prototype.templates.warnings,{hidden:function(t){t.visible||(0,u.default)("This collection has been hidden")}});return _.extend({},m.prototype.templates,{warnings:t,titleBar:function(t){return'\n <div class="title-bar clear" tabindex="0">\n <span class="state-icon"></span>\n <div class="title">\n <span class="hid">'+t.hid+'</span>\n <span class="name">'+_.escape(t.name)+'</span>\n </div>\n <div class="state-description">\n </div>\n '+p.default.nametagTemplate(t)+"\n </div>\n "}})}(),t.default={HDCAListItemView:h}});
+1 -1
View File
@@ -1 +1 @@
define("mvc/history/hdca-model",["exports","mvc/collection/collection-model","mvc/history/history-content-model","utils/localization"],function(t,e,o,i){"use strict";function s(t){return t&&t.__esModule?t:{default:t}}function l(t){return function(e,o){return this.isNew()&&((o=o||{}).url=this.urlRoot+this.get("history_id")+"/contents",(e=e||{}).type="dataset_collection"),t.call(this,e,o)}}Object.defineProperty(t,"__esModule",{value:!0});var n=s(e),a=s(o),c=(s(i),a.default.HistoryContentMixin),r=n.default.ListDatasetCollection,d=n.default.PairDatasetCollection,y=n.default.ListPairedDatasetCollection,u=n.default.ListOfListsDatasetCollection,p=r.extend(c).extend({defaults:_.extend(_.clone(r.prototype.defaults),{history_content_type:"dataset_collection",collection_type:"list",model_class:"HistoryDatasetCollectionAssociation"}),save:l(r.prototype.save),toString:function(){return"History"+r.prototype.toString.call(this)}}),f=d.extend(c).extend({defaults:_.extend(_.clone(d.prototype.defaults),{history_content_type:"dataset_collection",collection_type:"paired",model_class:"HistoryDatasetCollectionAssociation"}),save:l(d.prototype.save),toString:function(){return"History"+d.prototype.toString.call(this)}}),h=y.extend(c).extend({defaults:_.extend(_.clone(y.prototype.defaults),{history_content_type:"dataset_collection",collection_type:"list:paired",model_class:"HistoryDatasetCollectionAssociation"}),save:l(y.prototype.save),toString:function(){return"History"+y.prototype.toString.call(this)}}),x=u.extend(c).extend({defaults:_.extend(_.clone(u.prototype.defaults),{history_content_type:"dataset_collection",collection_type:"list:list",model_class:"HistoryDatasetCollectionAssociation"}),save:l(u.prototype.save),toString:function(){return"HistoryListOfListsDatasetCollection("+this.get("name")+")"}});t.default={HistoryListDatasetCollection:p,HistoryPairDatasetCollection:f,HistoryListPairedDatasetCollection:h,HistoryListOfListsDatasetCollection:x}});
define("mvc/history/hdca-model",["exports","mvc/collection/collection-model","mvc/history/history-content-model","utils/localization"],function(t,e,o,i){"use strict";function l(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(t,"__esModule",{value:!0});var n=l(e),s=l(o),c=(l(i),s.default.HistoryContentMixin),a=n.default.DatasetCollection,r=a.extend(c).extend({defaults:_.extend(_.clone(a.prototype.defaults),{history_content_type:"dataset_collection",model_class:"HistoryDatasetCollectionAssociation"}),save:function(t,e){return this.isNew()&&((e=e||{}).url=this.urlRoot+this.get("history_id")+"/contents",(t=t||{}).type="dataset_collection"),a.prototype.save.call(this,t,e)},toString:function(){return"History"+a.prototype.toString.call(this)}});t.default={HistoryDatasetCollection:r}});
File diff suppressed because one or more lines are too long
+5 -9
View File
@@ -64,19 +64,13 @@ class DatasetCollectionApiTestCase(api.ApiTestCase):
assert len(returned_collections) == 1, dataset_collection
def test_create_list_of_new_pairs(self):
pair_identifiers = self.dataset_collection_populator.pair_identifiers(self.history_id)
element_identifiers = [dict(
src="new_collection",
name="test_pair",
collection_type="paired",
element_identifiers=pair_identifiers,
)]
identifiers = self.dataset_collection_populator.nested_collection_identifiers(self.history_id, "list:paired")
payload = dict(
collection_type="list:paired",
instance_type="history",
history_id=self.history_id,
name="a nested collection",
element_identifiers=json.dumps(element_identifiers),
element_identifiers=json.dumps(identifiers),
)
create_response = self._post("dataset_collections", payload)
dataset_collection = self._check_create_response(create_response)
@@ -85,7 +79,9 @@ class DatasetCollectionApiTestCase(api.ApiTestCase):
returned_collections = dataset_collection["elements"]
assert len(returned_collections) == 1, dataset_collection
pair_1_element = returned_collections[0]
self._assert_has_keys(pair_1_element, "element_index")
self._assert_has_keys(pair_1_element, "element_identifier", "element_index", "object")
assert pair_1_element["element_identifier"] == "test_level_1", pair_1_element
assert pair_1_element["element_index"] == 0, pair_1_element
pair_1_object = pair_1_element["object"]
self._assert_has_keys(pair_1_object, "collection_type", "elements", "element_count")
self.assertEquals(pair_1_object["collection_type"], "paired")
+40 -10
View File
@@ -560,14 +560,42 @@ class BaseDatasetCollectionPopulator(object):
collection_type='list:paired',
name=name)
def create_nested_collection(self, history_id, collection, collection_type, name):
element_identifiers = []
for i, pair in enumerate(collection):
element_identifiers.append(dict(
name="test%d" % i,
src="hdca",
id=pair
))
def nested_collection_identifiers(self, history_id, collection_type):
rank_types = list(reversed(collection_type.split(":")))
assert len(rank_types) > 0
rank_type_0 = rank_types[0]
if rank_type_0 == "list":
identifiers = self.list_identifiers(history_id)
else:
identifiers = self.pair_identifiers(history_id)
nested_collection_type = rank_type_0
for i, rank_type in enumerate(reversed(rank_types[1:])):
name = "test_level_%d" % (i + 1) if rank_type == "list" else "paired"
identifiers = [dict(
src="new_collection",
name=name,
collection_type=nested_collection_type,
element_identifiers=identifiers,
)]
nested_collection_type = "%s:%s" % (rank_type, nested_collection_type)
return identifiers
def create_nested_collection(self, history_id, collection_type, name=None, collection=None, element_identifiers=None):
"""Create a nested collection either from collection or using collection_type)."""
assert collection_type is not None
name = name or "Test %s" % collection_type
if collection is not None:
assert element_identifiers is None
element_identifiers = []
for i, pair in enumerate(collection):
element_identifiers.append(dict(
name="test%d" % i,
src="hdca",
id=pair
))
if element_identifiers is None:
element_identifiers = self.nested_collection_identifiers(history_id, collection_type)
payload = dict(
instance_type="history",
@@ -583,6 +611,8 @@ class BaseDatasetCollectionPopulator(object):
return self.create_list_from_pairs(history_id, [pair1])
def create_list_of_list_in_history(self, history_id, **kwds):
# create_nested_collection will generate nested collection from just datasets,
# this function uses recursive generation of history hdcas.
collection_type = kwds.pop('collection_type', 'list:list')
collection_types = collection_type.split(':')
list = self.create_list_in_history(history_id, **kwds).json()['id']
@@ -590,9 +620,9 @@ class BaseDatasetCollectionPopulator(object):
for collection_type in collection_types[1:]:
current_collection_type = "%s:%s" % (current_collection_type, collection_type)
response = self.create_nested_collection(history_id=history_id,
collection=[list],
collection_type=current_collection_type,
name=current_collection_type)
name=current_collection_type,
collection=[list])
list = response.json()['id']
return response
+9
View File
@@ -43,6 +43,15 @@ class SelectorTemplate(Target):
assert self.selector_type == "css"
return SelectorTemplate(self._selector, self.selector_type, kwds=self.__kwds, with_classes=self.with_classes + [class_], children=self._children)
def descendant(self, has_selector):
assert self.selector_type == "css"
if hasattr(has_selector, "selector"):
selector = has_selector.selector
else:
selector = has_selector
return SelectorTemplate(self.selector + " " + selector, self.selector_type, kwds=self.__kwds, children=self._children)
def __call__(self, **kwds):
new_kwds = self.__kwds
new_kwds.update(**kwds)
+4
View File
@@ -153,6 +153,10 @@ class HasDriver:
**kwds
)
def click(self, selector_template):
element = self.driver.find_element(*selector_template.element_locator)
element.click()
def _wait_on(self, condition, on_str=None, **kwds):
if on_str is None:
on_str = str(condition)
+5
View File
@@ -908,6 +908,11 @@ class NavigatesGalaxy(HasDriver):
viz_menu_selectors = "%s %s" % (self.history_panel_item_selector(hid), "a.visualization-link")
return self.driver.find_elements_by_css_selector(viz_menu_selectors)
def history_panel_item_get_nametags(self, hid):
item_component = self.history_panel_item_component(hid=hid)
item_component.wait_for_visible()
return [e.text for e in item_component.nametags.all()]
def history_panel_item_available_visualizations(self, hid):
# Precondition: viz menu has been opened with history_panel_item_click_visualization_menu
return [e.text for e in self.history_panel_item_available_visualizations_elements(hid)]
+11
View File
@@ -92,6 +92,7 @@ history_panel:
download_button: '${_} .icon-btn.download-btn'
info_button: '${_} .icon-btn.params-btn'
rerun_button: '${_} .icon-btn.rerun-btn'
nametags: '${_} .nametags .label'
multi_operations:
selectors:
@@ -104,6 +105,16 @@ history_panel:
build_list: "Build Dataset List"
build_list_pairs: "Build List of Dataset Pairs"
collection_view:
selectors:
_: '.list-panel.dataset-collection-panel'
back: '.navigation .back'
title: '.dataset-collection-panel .controls .title .editable-text'
title_input: '.dataset-collection-panel .controls .title input'
subtitle: '.dataset-collection-panel .controls .title .subtitle'
tag_area_input: '.controls .tags-display .tags-input input'
list_items: '.dataset-collection-panel .list-items .list-item'
selectors:
_: '#current-history-panel'
search: '#current-history-panel input.search-query'
+3
View File
@@ -53,6 +53,9 @@ class SmartTarget(object):
else:
return simple_object
def all(self):
return self._has_driver.driver.find_elements(*self._target.element_locator)
def wait_for_and_click(self, **kwds):
return self._has_driver.wait_for_and_click(self._target, **kwds)
@@ -22,3 +22,46 @@ class HistoryMultiViewTestCase(SeleniumTestCase):
self.components.multi_history_view.create_new_button.wait_for_and_click()
self.components.multi_history_view.drag_drop_help.wait_for_visible()
self.wait_for_visible(hdca_selector)
self.screenshot("multi_history_collection")
@selenium_test
def test_list_list_display(self):
history_id = self.current_history_id()
collection = self.dataset_collection_populator.create_list_of_list_in_history(history_id).json()
collection_hid = collection["hid"]
self.home()
self.components.history_panel.multi_view_button.wait_for_and_click()
selector = self.history_panel_wait_for_hid_state(collection_hid, "ok")
self.click(selector)
first_level_element_selector = selector.descendant(".dataset-collection-element")
self.wait_for_and_click(first_level_element_selector)
dataset_selector = first_level_element_selector.descendant(".dataset")
self.wait_for_and_click(dataset_selector)
self.sleep_for(self.wait_types.UX_TRANSITION)
self.screenshot("multi_history_list_list")
@selenium_test
def test_list_list_list_display(self):
history_id = self.current_history_id()
collection = self.dataset_collection_populator.create_nested_collection(history_id, collection_type="list:list:list").json()
collection_hid = collection["hid"]
self.home()
self.components.history_panel.multi_view_button.wait_for_and_click()
selector = self.history_panel_wait_for_hid_state(collection_hid, "ok")
self.click(selector)
first_level_element_selector = selector.descendant(".dataset-collection-element")
self.wait_for_and_click(first_level_element_selector)
second_level_element_selector = first_level_element_selector.descendant(".dataset-collection-element")
self.wait_for_and_click(second_level_element_selector)
dataset_selector = first_level_element_selector.descendant(".dataset")
self.wait_for_and_click(dataset_selector)
self.sleep_for(self.wait_types.UX_TRANSITION)
self.screenshot("multi_history_list_list_list")
@@ -4,6 +4,7 @@ from base.api_asserts import assert_status_code_is
from base.populators import flakey
from .framework import (
retry_assertion_during_transitions,
selenium_test,
SeleniumTestCase
)
@@ -16,12 +17,9 @@ class HistoryPanelCollectionsTestCase(SeleniumTestCase):
@selenium_test
def test_mapping_collection_states_terminal(self):
history_id = self.current_history_id()
input_collection = self.dataset_collection_populator.create_list_in_history(history_id, contents=["0", "1", "0", "1"]).json()
input_collection, failed_collection = self._generate_partially_failed_collection_with_input()
input_hid = input_collection["hid"]
failed_response = self.dataset_populator.run_exit_code_from_file(history_id, input_collection["id"])
failed_hid = failed_response["implicit_collections"][0]["hid"]
failed_hid = failed_collection["hid"]
ok_inputs = {
"input1": {'batch': True, 'values': [{"src": "hdca", "id": input_collection["id"]}]},
"sleep_time": 0,
@@ -130,3 +128,117 @@ class HistoryPanelCollectionsTestCase(SeleniumTestCase):
finally:
for job in running_response.json()["jobs"]:
self.dataset_populator.cancel_job(job["id"])
@selenium_test
def test_collection_operations(self):
# Test back and rename.
input_collection = self._populated_paired_and_wait_for_it()
collection_hid = input_collection["hid"]
collection_view = self._click_and_wait_for_collection_view(collection_hid)
collection_view.back.wait_for_and_click()
self.history_panel_wait_for_hid_state(collection_hid, "ok")
self._click_and_wait_for_collection_view(collection_hid)
title_element = collection_view.title.wait_for_visible()
assert title_element.text == input_collection["name"]
title_element.click()
title_rename_element = collection_view.title_input.wait_for_visible()
self.screenshot("history_panel_collection_view_rename")
title_rename_element.send_keys("My New Name")
self.send_enter(title_rename_element)
title_element = collection_view.title.wait_for_visible()
assert title_element.text == "My New Name"
@selenium_test
def test_name_tags_display(self):
# Test setting a name tag and viewing it from the outer history panel.
input_collection = self._populated_paired_and_wait_for_it()
collection_hid = input_collection["hid"]
collection_view = self._click_and_wait_for_collection_view(collection_hid)
self.tagging_add(["#moo"])
self.screenshot("history_panel_collection_view_add_nametag")
collection_view.back.wait_for_and_click()
self.history_panel_wait_for_hid_state(collection_hid, "ok")
nametags = self.history_panel_item_get_nametags(collection_hid)
assert nametags == ["moo"]
self.screenshot("history_panel_collection_with_nametag")
@selenium_test
def test_paired_display(self):
input_collection = self._populated_paired_and_wait_for_it()
collection_hid = input_collection["hid"]
collection_view = self._click_and_wait_for_collection_view(collection_hid)
dataset_elements = collection_view.list_items.all()
assert len(dataset_elements) == 2, dataset_elements
title_elements = [de.find_element_by_css_selector(".title .name").text for de in dataset_elements]
assert title_elements == ["forward", "reverse"]
self.screenshot("history_panel_collection_view_paired")
@selenium_test
@flakey # Fails only in Jenkins full suite - possibly due to #3782.
def test_list_display(self):
_, failed_collection = self._generate_partially_failed_collection_with_input()
failed_hid = failed_collection["hid"]
self.home()
self.history_panel_wait_for_hid_state(failed_hid, "error")
collection_view = self._click_and_wait_for_collection_view(failed_hid)
@retry_assertion_during_transitions
def check_four_datasets_shown():
dataset_elements = collection_view.list_items.all()
assert len(dataset_elements) == 4, dataset_elements
title_elements = [de.find_element_by_css_selector(".title .name").text for de in dataset_elements]
assert title_elements == ["data1", "data2", "data3", "data4"]
check_four_datasets_shown()
self.screenshot("history_panel_collection_view_list")
@selenium_test
def test_list_paired_display(self):
history_id = self.current_history_id()
collection = self.dataset_collection_populator.create_list_of_pairs_in_history(history_id).json()
collection_hid = collection["hid"]
self.home()
self.history_panel_wait_for_hid_state(collection_hid, "ok")
self._click_and_wait_for_collection_view(collection_hid)
self.screenshot("history_panel_collection_view_list_paired")
@selenium_test
def test_list_list_display(self):
history_id = self.current_history_id()
collection = self.dataset_collection_populator.create_list_of_list_in_history(history_id).json()
collection_hid = collection["hid"]
self.home()
self.history_panel_wait_for_hid_state(collection_hid, "ok")
self._click_and_wait_for_collection_view(collection_hid)
self.screenshot("history_panel_collection_view_list_list")
def _generate_partially_failed_collection_with_input(self):
history_id = self.current_history_id()
input_collection = self.dataset_collection_populator.create_list_in_history(history_id, contents=["0", "1", "0", "1"]).json()
failed_response = self.dataset_populator.run_exit_code_from_file(history_id, input_collection["id"])
failed_collection = failed_response["implicit_collections"][0]
return input_collection, failed_collection
def _click_and_wait_for_collection_view(self, collection_hid):
self.history_panel_click_item_title(collection_hid)
collection_view = self.components.history_panel.collection_view
collection_view._.wait_for_visible()
return collection_view
def _populated_paired_and_wait_for_it(self):
history_id = self.current_history_id()
input_collection = self.dataset_collection_populator.create_pair_in_history(history_id).json()
collection_hid = input_collection["hid"]
self.home()
self.history_panel_wait_for_hid_state(collection_hid, "ok")
return input_collection