diff --git a/client/galaxy/scripts/mvc/workflow/workflow-forms.js b/client/galaxy/scripts/mvc/workflow/workflow-forms.js index 5417e35ff2f1..40bdbcd59149 100644 --- a/client/galaxy/scripts/mvc/workflow/workflow-forms.js +++ b/client/galaxy/scripts/mvc/workflow/workflow-forms.js @@ -98,12 +98,14 @@ var Tool = Backbone.View.extend({ __class__: "RuntimeValue" }; input.is_workflow = - (input.options && input.options.length == 0) || ["integer", "float"].indexOf(input.type) != -1; + (input.options && input.options.length === 0) || ["integer", "float"].indexOf(input.type) != -1; } } }); Utils.deepeach(options.inputs, input => { - input.type == "conditional" && (input.test_param.collapsible_value = undefined); + if (input.type === "conditional") { + input.test_param.collapsible_value = undefined; + } }); _addSections(form); _addLabelAnnotation(form); @@ -151,181 +153,185 @@ function _addLabelAnnotation(form) { }); } -/** Builds all sub sections */ -function _addSections(form) { - var options = form.model.attributes; - var inputs = options.inputs; - var datatypes = options.datatypes; - var node = options.node; - var workflow = options.workflow; - var post_job_actions = node.post_job_actions; - var output_id = node.output_terminals && Object.keys(node.output_terminals)[0]; - - /** Visit input nodes and enrich by name/value pairs from server data */ - function visit(head, head_list) { - head_list = head_list || []; - head_list.push(head); - for (var i in head.inputs) { - var input = head.inputs[i]; - var action = input.action; - if (action) { - input.name = `pja__${output_id}__${input.action}`; - if (input.pja_arg) { - input.name += `__${input.pja_arg}`; +/** Visit input nodes and enrich by name/value pairs from server data */ +function _visit(head, head_list, output_id, options) { + var post_job_actions = options.node.post_job_actions; + head_list = head_list || []; + head_list.push(head); + for (var i in head.inputs) { + var input = head.inputs[i]; + var action = input.action; + if (action) { + input.name = `pja__${output_id}__${input.action}`; + if (input.pja_arg) { + input.name += `__${input.pja_arg}`; + } + if (input.payload) { + for (var p_id in input.payload) { + input.payload[`${input.name}__${p_id}`] = input.payload[p_id]; + delete input.payload[p_id]; } - if (input.payload) { - for (var p_id in input.payload) { - input.payload[`${input.name}__${p_id}`] = input.payload[p_id]; - delete input.payload[p_id]; - } + } + var d = post_job_actions[input.action + output_id]; + if (d) { + for (var j in head_list) { + head_list[j].expanded = true; } - var d = post_job_actions[input.action + output_id]; - if (d) { - for (var j in head_list) { - head_list[j].expanded = true; - } - if (input.pja_arg) { - input.value = (d.action_arguments && d.action_arguments[input.pja_arg]) || input.value; - } else { - input.value = "true"; - } + if (input.pja_arg) { + input.value = (d.action_arguments && d.action_arguments[input.pja_arg]) || input.value; + } else { + input.value = "true"; } } - input.inputs && visit(input, head_list.slice(0)); + } + if (input.inputs) { + _visit(input, head_list.slice(0), output_id, options); } } +} - /** Builds sub section with step actions/annotation */ - function _makeSection(output_id, datatypes) { - var extensions = []; - var input_terminal_names = []; - for (var key in datatypes) { - extensions.push({ 0: datatypes[key], 1: datatypes[key] }); - } - for (key in node.input_terminals) { - input_terminal_names.push(node.input_terminals[key].name); - } - extensions.sort((a, b) => (a.label > b.label ? 1 : a.label < b.label ? -1 : 0)); - extensions.unshift({ - 0: "Sequences", - 1: "Sequences" - }); - extensions.unshift({ - 0: "Roadmaps", - 1: "Roadmaps" - }); - extensions.unshift({ - 0: "Leave unchanged", - 1: "__empty__" - }); - var output; - var input_config = { - title: `Configure Output: '${output_id}'`, - type: "section", - flat: true, - inputs: [ - { - label: "Label", - type: "text", - value: ((output = node.getWorkflowOutput(output_id)) && output.label) || "", - help: - "This will provide a short name to describe the output - this must be unique across workflows.", - onchange: function(new_value) { - workflow.attemptUpdateOutputLabel(node, output_id, new_value); - } - }, - { - action: "RenameDatasetAction", - pja_arg: "newname", - label: "Rename dataset", - type: "text", - value: "", - ignore: "", - help: `This action will rename the output dataset. Click here for more information. Valid inputs are: ${input_terminal_names.join( - ", " - )}.` - }, - { - action: "ChangeDatatypeAction", - pja_arg: "newtype", - label: "Change datatype", - type: "select", - ignore: "__empty__", - value: "__empty__", - options: extensions, - help: "This action will change the datatype of the output to the indicated value." - }, - { - action: "TagDatasetAction", - pja_arg: "tags", - label: "Add Tags", - type: "text", - value: "", - ignore: "", - help: "This action will set tags for the dataset." - }, - { - action: "RemoveTagDatasetAction", - pja_arg: "tags", - label: "Remove Tags", - type: "text", - value: "", - ignore: "", - help: "This action will remove tags for the dataset." - }, - { - title: "Assign columns", - type: "section", - flat: true, - inputs: [ - { - action: "ColumnSetAction", - pja_arg: "chromCol", - label: "Chrom column", - type: "integer", - value: "", - ignore: "" - }, - { - action: "ColumnSetAction", - pja_arg: "startCol", - label: "Start column", - type: "integer", - value: "", - ignore: "" - }, - { - action: "ColumnSetAction", - pja_arg: "endCol", - label: "End column", - type: "integer", - value: "", - ignore: "" - }, - { - action: "ColumnSetAction", - pja_arg: "strandCol", - label: "Strand column", - type: "integer", - value: "", - ignore: "" - }, - { - action: "ColumnSetAction", - pja_arg: "nameCol", - label: "Name column", - type: "integer", - value: "", - ignore: "" - } - ], - help: "This action will set column assignments in the output dataset. Blank fields are ignored." - } - ] - }; - visit(input_config); - return input_config; +/** Builds sub section with step actions/annotation */ +function _makeSection(output_id, options) { + var extensions = []; + var input_terminal_names = []; + var datatypes = options.datatypes; + var node = options.node; + var workflow = options.workflow; + + for (var key in datatypes) { + extensions.push({ 0: datatypes[key], 1: datatypes[key] }); + } + for (key in node.input_terminals) { + input_terminal_names.push(node.input_terminals[key].name); } + extensions.sort((a, b) => (a.label > b.label ? 1 : a.label < b.label ? -1 : 0)); + extensions.unshift({ + 0: "Sequences", + 1: "Sequences" + }); + extensions.unshift({ + 0: "Roadmaps", + 1: "Roadmaps" + }); + extensions.unshift({ + 0: "Leave unchanged", + 1: "__empty__" + }); + var output; + var input_config = { + title: `Configure Output: '${output_id}'`, + type: "section", + flat: true, + inputs: [ + { + label: "Label", + type: "text", + value: ((output = node.getWorkflowOutput(output_id)) && output.label) || "", + help: "This will provide a short name to describe the output - this must be unique across workflows.", + onchange: function(new_value) { + workflow.attemptUpdateOutputLabel(node, output_id, new_value); + } + }, + { + action: "RenameDatasetAction", + pja_arg: "newname", + label: "Rename dataset", + type: "text", + value: "", + ignore: "", + help: `This action will rename the output dataset. Click here for more information. Valid inputs are: ${input_terminal_names.join( + ", " + )}.` + }, + { + action: "ChangeDatatypeAction", + pja_arg: "newtype", + label: "Change datatype", + type: "select", + ignore: "__empty__", + value: "__empty__", + options: extensions, + help: "This action will change the datatype of the output to the indicated value." + }, + { + action: "TagDatasetAction", + pja_arg: "tags", + label: "Add Tags", + type: "text", + value: "", + ignore: "", + help: "This action will set tags for the dataset." + }, + { + action: "RemoveTagDatasetAction", + pja_arg: "tags", + label: "Remove Tags", + type: "text", + value: "", + ignore: "", + help: "This action will remove tags for the dataset." + }, + { + title: "Assign columns", + type: "section", + flat: true, + inputs: [ + { + action: "ColumnSetAction", + pja_arg: "chromCol", + label: "Chrom column", + type: "integer", + value: "", + ignore: "" + }, + { + action: "ColumnSetAction", + pja_arg: "startCol", + label: "Start column", + type: "integer", + value: "", + ignore: "" + }, + { + action: "ColumnSetAction", + pja_arg: "endCol", + label: "End column", + type: "integer", + value: "", + ignore: "" + }, + { + action: "ColumnSetAction", + pja_arg: "strandCol", + label: "Strand column", + type: "integer", + value: "", + ignore: "" + }, + { + action: "ColumnSetAction", + pja_arg: "nameCol", + label: "Name column", + type: "integer", + value: "", + ignore: "" + } + ], + help: "This action will set column assignments in the output dataset. Blank fields are ignored." + } + ] + }; + _visit(input_config, [], output_id, options); + return input_config; +} + +/** Builds all sub sections */ +function _addSections(form) { + var options = form.model.attributes; + var inputs = options.inputs; + var node = options.node; + var post_job_actions = node.post_job_actions; + var output_id = node.output_terminals && Object.keys(node.output_terminals)[0]; if (output_id) { inputs.push({ @@ -349,7 +355,7 @@ function _addSections(form) { "Upon completion of this step, delete non-starred outputs from completed workflow steps if they are no longer required as inputs." }); for (var i in node.output_terminals) { - inputs.push(_makeSection(i, datatypes)); + inputs.push(_makeSection(i, options)); } } } diff --git a/client/galaxy/scripts/mvc/workflow/workflow-node.js b/client/galaxy/scripts/mvc/workflow/workflow-node.js index 38fad8b1dfc0..a14919d35e32 100644 --- a/client/galaxy/scripts/mvc/workflow/workflow-node.js +++ b/client/galaxy/scripts/mvc/workflow/workflow-node.js @@ -14,7 +14,7 @@ var Node = Backbone.Model.extend({ }); }, isWorkflowOutput: function(outputName) { - return this.getWorkflowOutput(outputName) != undefined; + return this.getWorkflowOutput(outputName) !== undefined; }, removeWorkflowOutput: function(outputName) { while (this.isWorkflowOutput(outputName)) { @@ -25,7 +25,7 @@ var Node = Backbone.Model.extend({ if (!this.isWorkflowOutput(outputName)) { var output = { output_name: outputName }; if (label) { - output["label"] = label; + output.label = label; } this.workflow_outputs.push(output); return true; @@ -37,8 +37,8 @@ var Node = Backbone.Model.extend({ var oldLabel = null; if (this.isWorkflowOutput(outputName)) { var workflowOutput = this.getWorkflowOutput(outputName); - oldLabel = workflowOutput["label"]; - workflowOutput["label"] = label; + oldLabel = workflowOutput.label; + workflowOutput.label = label; changed = oldLabel != label; } else { changed = this.addWorkflowOutput(outputName, label); @@ -239,7 +239,7 @@ var Node = Backbone.Model.extend({ this.config_form = data.config_form; this.tool_version = this.config_form && this.config_form.version; this.errors = data.errors; - this.annotation = data["annotation"]; + this.annotation = data.annotation; this.label = data.label; if ("post_job_actions" in data) { // Won't be present in response for data inputs @@ -271,7 +271,7 @@ var Node = Backbone.Model.extend({ old_body.replaceWith(new_body); if ("workflow_outputs" in data) { // Won't be present in response for data inputs - this.workflow_outputs = workflow_outputs ? workflow_outputs : []; + this.workflow_outputs = data.workflow_outputs ? data.workflow_outputs : []; } // If active, reactivate with new config_form this.markChanged(); diff --git a/config/datatypes_conf.xml.sample b/config/datatypes_conf.xml.sample index 56437b395b6b..d1b1500c955e 100644 --- a/config/datatypes_conf.xml.sample +++ b/config/datatypes_conf.xml.sample @@ -146,6 +146,7 @@ + @@ -677,6 +678,7 @@ + diff --git a/lib/galaxy/datatypes/binary.py b/lib/galaxy/datatypes/binary.py index f5814dff02ce..1d69cbba5fb0 100644 --- a/lib/galaxy/datatypes/binary.py +++ b/lib/galaxy/datatypes/binary.py @@ -25,7 +25,6 @@ from galaxy.util.checkers import is_bz2, is_gzip from . import data, dataproviders - log = logging.getLogger(__name__) # Currently these supported binary data types must be manually set on upload @@ -890,6 +889,60 @@ def display_peek(self, dataset): return "Biom2 (HDF5) file (%s)" % (nice_size(dataset.get_size())) +class Cool(H5): + """ + Class describing the cool format (https://github.com/mirnylab/cooler) + """ + + file_ext = "cool" + + def sniff(self, filename): + """ + >>> from galaxy.datatypes.sniff import get_test_fname + >>> fname = get_test_fname( 'matrix.cool' ) + >>> Cool().sniff( fname ) + True + >>> fname = get_test_fname( 'test.mz5' ) + >>> Cool().sniff( fname ) + False + >>> fname = get_test_fname( 'wiggle.wig' ) + >>> Cool().sniff( fname ) + False + >>> fname = get_test_fname( 'biom2_sparse_otu_table_hdf5.biom' ) + >>> Cool().sniff( fname ) + False + """ + + MAGIC = "HDF5::Cooler" + URL = "https://github.com/mirnylab/cooler" + + if super(Cool, self).sniff(filename): + keys = ['chroms', 'bins', 'pixels', 'indexes'] + with h5py.File(filename, 'r') as handle: + fmt = handle.attrs.get('format', None) + url = handle.attrs.get('format-url', None) + if fmt == MAGIC or url == URL: + if not all(name in handle.keys() for name in keys): + return False + return True + return False + + def set_peek(self, dataset, is_multi_byte=False): + if not dataset.dataset.purged: + dataset.peek = "Cool (HDF5) file for storing genomic interaction data." + dataset.blurb = nice_size(dataset.get_size()) + else: + dataset.peek = 'file does not exist' + dataset.blurb = 'file purged from disk' + + def display_peek(self, dataset): + try: + return dataset.peek + except Exception: + return "Cool (HDF5) file (%s)." % (nice_size(dataset.get_size())) + + +Binary.register_sniffable_binary_format("cool", "cool", Cool) Binary.register_sniffable_binary_format("biom2", "biom2", Biom2) Binary.register_sniffable_binary_format("h5", "h5", H5) diff --git a/lib/galaxy/datatypes/test/matrix.cool b/lib/galaxy/datatypes/test/matrix.cool new file mode 100644 index 000000000000..91ec17bb85ff Binary files /dev/null and b/lib/galaxy/datatypes/test/matrix.cool differ diff --git a/lib/galaxy/jobs/metrics/instrumenters/core.py b/lib/galaxy/jobs/metrics/instrumenters/core.py index 86c923d69b74..c17af4bc55d4 100644 --- a/lib/galaxy/jobs/metrics/instrumenters/core.py +++ b/lib/galaxy/jobs/metrics/instrumenters/core.py @@ -8,6 +8,7 @@ log = logging.getLogger(__name__) GALAXY_SLOTS_KEY = "galaxy_slots" +GALAXY_MEMORY_MB_KEY = "galaxy_memory_mb" START_EPOCH_KEY = "start_epoch" END_EPOCH_KEY = "end_epoch" RUNTIME_SECONDS_KEY = "runtime_seconds" @@ -19,6 +20,8 @@ def format(self, key, value): value = int(value) if key == GALAXY_SLOTS_KEY: return ("Cores Allocated", "%d" % value) + elif key == GALAXY_MEMORY_MB_KEY: + return ("Memory Allocated (MB)", "%d" % value) elif key == RUNTIME_SECONDS_KEY: return ("Job Runtime (Wall Clock)", formatting.seconds_to_str(value)) else: @@ -40,6 +43,7 @@ def __init__(self, **kwargs): def pre_execute_instrument(self, job_directory): commands = [] commands.append(self.__record_galaxy_slots_command(job_directory)) + commands.append(self.__record_galaxy_memory_mb_command(job_directory)) commands.append(self.__record_seconds_since_epoch_to_file(job_directory, "start")) return commands @@ -50,9 +54,11 @@ def post_execute_instrument(self, job_directory): def job_properties(self, job_id, job_directory): galaxy_slots_file = self.__galaxy_slots_file(job_directory) + galaxy_memory_mb_file = self.__galaxy_memory_mb_file(job_directory) properties = {} properties[GALAXY_SLOTS_KEY] = self.__read_integer(galaxy_slots_file) + properties[GALAXY_MEMORY_MB_KEY] = self.__read_integer(galaxy_memory_mb_file) start = self.__read_seconds_since_epoch(job_directory, "start") end = self.__read_seconds_since_epoch(job_directory, "end") if start is not None and end is not None: @@ -65,6 +71,10 @@ def __record_galaxy_slots_command(self, job_directory): galaxy_slots_file = self.__galaxy_slots_file(job_directory) return '''echo "$GALAXY_SLOTS" > '%s' ''' % galaxy_slots_file + def __record_galaxy_memory_mb_command(self, job_directory): + galaxy_memory_mb_file = self.__galaxy_memory_mb_file(job_directory) + return '''echo "$GALAXY_MEMORY_MB" > '%s' ''' % galaxy_memory_mb_file + def __record_seconds_since_epoch_to_file(self, job_directory, name): path = self._instrument_file_path(job_directory, "epoch_%s" % name) return 'date +"%s" > ' + path @@ -76,6 +86,9 @@ def __read_seconds_since_epoch(self, job_directory, name): def __galaxy_slots_file(self, job_directory): return self._instrument_file_path(job_directory, "galaxy_slots") + def __galaxy_memory_mb_file(self, job_directory): + return self._instrument_file_path(job_directory, "galaxy_memory_mb") + def __read_integer(self, path): value = None try: diff --git a/lib/galaxy/managers/collections.py b/lib/galaxy/managers/collections.py index 7f388828137f..0e6420a43c31 100644 --- a/lib/galaxy/managers/collections.py +++ b/lib/galaxy/managers/collections.py @@ -187,14 +187,17 @@ def update(self, trans, instance_type, id, payload): changed = self._set_from_dict(trans, dataset_collection_instance, payload) return changed - def copy(self, trans, parent, source, encoded_source_id): + def copy(self, trans, parent, source, encoded_source_id, copy_elements=False): """ PRECONDITION: security checks on ability to add to parent occurred during load. """ assert source == "hdca" # for now source_hdca = self.__get_history_collection_instance(trans, encoded_source_id) - new_hdca = source_hdca.copy() + copy_kwds = {} + if copy_elements: + copy_kwds["element_destination"] = parent + new_hdca = source_hdca.copy(**copy_kwds) tags_str = self.tag_manager.get_tags_str(source_hdca.tags) self.tag_manager.apply_item_tags(trans.get_user(), new_hdca, tags_str) parent.add_dataset_collection(new_hdca) diff --git a/lib/galaxy/webapps/galaxy/api/configuration.py b/lib/galaxy/webapps/galaxy/api/configuration.py index 63843062b991..25f4f8d9e96a 100644 --- a/lib/galaxy/webapps/galaxy/api/configuration.py +++ b/lib/galaxy/webapps/galaxy/api/configuration.py @@ -90,6 +90,18 @@ def dynamic_tool_confs(self, trans): confs = self.app.toolbox.dynamic_confs(include_migrated_tool_conf=True) return map(_tool_conf_to_dict, confs) + @expose_api + @require_admin + def decode_id(self, trans, encoded_id, **kwds): + """Decode a given id.""" + decoded_id = None + # Handle the special case for library folders + if ((len(encoded_id) % 16 == 1) and encoded_id.startswith('F')): + decoded_id = trans.security.decode_id(encoded_id[1:]) + else: + decoded_id = trans.security.decode_id(encoded_id) + return {"decoded_id": decoded_id} + @expose_api @require_admin def tool_lineages(self, trans): diff --git a/lib/galaxy/webapps/galaxy/api/history_contents.py b/lib/galaxy/webapps/galaxy/api/history_contents.py index 673a217b7270..f881fd8822fe 100644 --- a/lib/galaxy/webapps/galaxy/api/history_contents.py +++ b/lib/galaxy/webapps/galaxy/api/history_contents.py @@ -252,6 +252,9 @@ def create(self, trans, history_id, payload, **kwd): copy from history dataset collection (for type 'dataset_collection') 'source' = 'hdca' 'content' = [the encoded id from the HDCA] + 'copy_elements' = Copy child HDAs into the target history as well, + defaults to False but this is less than ideal and may + be changed in future releases. create new history dataset collection (for type 'dataset_collection') 'source' = 'new_collection' (default 'source' if type is @@ -434,11 +437,13 @@ def __create_dataset_collection(self, trans, history, payload, **kwd): content = payload.get('content', None) if content is None: raise exceptions.RequestParameterMissingException("'content' id of target to copy is missing") + copy_elements = payload.get('copy_elements', False) dataset_collection_instance = service.copy( trans=trans, parent=history, source="hdca", encoded_source_id=content, + copy_elements=copy_elements, ) else: message = "Invalid 'source' parameter in request %s" % source diff --git a/lib/galaxy/webapps/galaxy/buildapp.py b/lib/galaxy/webapps/galaxy/buildapp.py index 3e0c2fc43a95..b50e489038fe 100644 --- a/lib/galaxy/webapps/galaxy/buildapp.py +++ b/lib/galaxy/webapps/galaxy/buildapp.py @@ -341,6 +341,10 @@ def populate_api_routes(webapp, app): "/api/whoami", controller='configuration', action='whoami', conditions=dict(method=["GET"])) + webapp.mapper.connect("api_decode", + "/api/configuration/decode/{encoded_id}", controller='configuration', + action='decode_id', + conditions=dict(method=["GET"])) webapp.mapper.resource('datatype', 'datatypes', path_prefix='/api', diff --git a/lib/galaxy/workflow/scheduling_manager.py b/lib/galaxy/workflow/scheduling_manager.py index a815f6123238..8ce11db5601b 100644 --- a/lib/galaxy/workflow/scheduling_manager.py +++ b/lib/galaxy/workflow/scheduling_manager.py @@ -204,10 +204,10 @@ def __attempt_schedule(self, invocation_id, workflow_scheduler): sa_session = self.app.model.context workflow_invocation = sa_session.query(model.WorkflowInvocation).get(invocation_id) - if not workflow_invocation or not workflow_invocation.active: - return False - try: + if not workflow_invocation or not workflow_invocation.active: + return False + # This ensures we're only ever working on the 'first' active # workflow invocation in a given history, to force sequential # activation. @@ -220,6 +220,8 @@ def __attempt_schedule(self, invocation_id, workflow_scheduler): # TODO: eventually fail this - or fail it right away? log.exception("Exception raised while attempting to schedule workflow request.") return False + finally: + sa_session.expunge_all() # A workflow was obtained and scheduled... return True diff --git a/run_tests.sh b/run_tests.sh index f03420f3ae5a..cbb7d3207a8e 100755 --- a/run_tests.sh +++ b/run_tests.sh @@ -76,6 +76,13 @@ Run all selenium tests (Under Linux using Docker): Run a specific selenium test (under Linux or Mac OS X after installing geckodriver or chromedriver): ./run_tests.sh -selenium test/selenium_tests/test_registration.py:RegistrationTestCase.test_reregister_username_fails +Run a selenium test against a running server while watching client (fastest iterating on client tests): + ./run.sh & # run Galaxy on 8080 + make client-watch & # watch for client changes + export GALAXY_TEST_EXTERNAL=http://localhost:8080/ # Target tests at server. + . .venv/bin/activate # source the virtualenv so can skip run_tests.sh. + nosetests test/selenium_tests/test_workflow_editor.py:WorkflowEditorTestCase.test_data_input + Note About Selenium Tests: If using a local selenium driver such as a Chrome or Firefox based one diff --git a/static/maps/mvc/workflow/workflow-forms.js.map b/static/maps/mvc/workflow/workflow-forms.js.map index 6dfe075acf1a..ac3d4d2d5bbc 100644 --- a/static/maps/mvc/workflow/workflow-forms.js.map +++ b/static/maps/mvc/workflow/workflow-forms.js.map @@ -1 +1 @@ -{"version":3,"sources":["mvc/workflow/workflow-forms.js"],"names":["_addLabelAnnotation","form","options","model","attributes","workflow","input","type","inputs","unshift","_addSections","label","fixed","value","node","annotation","area","help","name","i","nodes","n","new_label","id","duplicate","data","match","element_list","input_id","set","trigger","input_element","head_list","datatypes","post_job_actions","output_terminals","output_id","action","visit","head","pja_arg","payload","p_id","d","expanded","action_arguments","slice","Object","keys","ignore","host","String","Boolean","push","window","location","Default","Tool","extensions","input_terminal_names","0","key","1","input_terminals","a","b","output","input_config","flat","getWorkflowOutput","title","attemptUpdateOutputLabel","new_value","onchange","join","Backbone","View","extend","initialize","self","this","_formView2","default","_utils2","merge","request","url","Galaxy","root","content_id","create","update_field_data","success","_toolFormBase2","text_enable","text_disable","initial_errors","cls","initialmodel","process","_customize","resolve","get","postchange","tool_id","version","$","current_state","buildmodel","config_form","tool_version","emit","debug","response","deepeach","error","indexOf","info","textify","__class__","collapsible_value","is_workflow","length","test_param","undefined"],"mappings":"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","file":"../../../scripts/mvc/workflow/workflow-forms.js","sourcesContent":["import Utils from \"utils/utils\";\nimport Form from \"mvc/form/form-view\";\nimport ToolFormBase from \"mvc/tool/tool-form-base\";\n/** Default form wrapper for non-tool modules in the workflow editor. */\nvar Default = Backbone.View.extend({\n initialize: function(options) {\n var self = this;\n var node = options.node;\n this.form = new Form(\n Utils.merge(options, {\n onchange: function() {\n Utils.request({\n type: \"POST\",\n url: `${Galaxy.root}api/workflows/build_module`,\n data: {\n id: node.id,\n type: node.type,\n content_id: node.content_id,\n inputs: self.form.data.create()\n },\n success: function(data) {\n node.update_field_data(data);\n }\n });\n }\n })\n );\n _addLabelAnnotation(this.form);\n this.form.render();\n }\n});\n\n/** Tool form wrapper for the workflow editor. */\nvar Tool = Backbone.View.extend({\n initialize: function(options) {\n var self = this;\n var node = options.node;\n this.form = new ToolFormBase(\n Utils.merge(options, {\n text_enable: \"Set in Advance\",\n text_disable: \"Set at Runtime\",\n narrow: true,\n initial_errors: true,\n cls: \"ui-portlet-narrow\",\n initialmodel: function(process, form) {\n self._customize(form);\n process.resolve();\n },\n buildmodel: function(process, form) {\n form.model.get(\"postchange\")(process, form);\n },\n postchange: function(process, form) {\n var options = form.model.attributes;\n var current_state = {\n tool_id: options.id,\n tool_version: options.version,\n type: \"tool\",\n inputs: $.extend(true, {}, form.data.create())\n };\n Galaxy.emit.debug(\"tool-form-workflow::postchange()\", \"Sending current state.\", current_state);\n Utils.request({\n type: \"POST\",\n url: `${Galaxy.root}api/workflows/build_module`,\n data: current_state,\n success: function(data) {\n form.model.set(data.config_form);\n self._customize(form);\n form.update(data.config_form);\n form.errors(data.config_form);\n // This hasn't modified the workflow, just returned\n // module information for the tool to update the workflow\n // state stored on the client with. User needs to save\n // for this to take effect.\n node.update_field_data(data);\n Galaxy.emit.debug(\"tool-form-workflow::postchange()\", \"Received new model.\", data);\n process.resolve();\n },\n error: function(response) {\n Galaxy.emit.debug(\"tool-form-workflow::postchange()\", \"Refresh request failed.\", response);\n process.reject();\n }\n });\n }\n })\n );\n },\n\n _customize: function(form) {\n var options = form.model.attributes;\n Utils.deepeach(options.inputs, input => {\n if (input.type) {\n if ([\"data\", \"data_collection\"].indexOf(input.type) != -1) {\n input.type = \"hidden\";\n input.info = `Data input '${input.name}' (${Utils.textify(input.extensions)})`;\n input.value = { __class__: \"RuntimeValue\" };\n } else if (!input.fixed) {\n input.collapsible_value = {\n __class__: \"RuntimeValue\"\n };\n input.is_workflow =\n (input.options && input.options.length == 0) || [\"integer\", \"float\"].indexOf(input.type) != -1;\n }\n }\n });\n Utils.deepeach(options.inputs, input => {\n input.type == \"conditional\" && (input.test_param.collapsible_value = undefined);\n });\n _addSections(form);\n _addLabelAnnotation(form);\n }\n});\n\n/** Augments the module form definition by adding label and annotation fields */\nfunction _addLabelAnnotation(form) {\n var options = form.model.attributes;\n var workflow = options.workflow;\n var node = options.node;\n options.inputs.unshift({\n type: \"text\",\n name: \"__annotation\",\n label: \"Annotation\",\n fixed: true,\n value: node.annotation,\n area: true,\n help: \"Add an annotation or notes to this step. Annotations are available when a workflow is viewed.\"\n });\n options.inputs.unshift({\n type: \"text\",\n name: \"__label\",\n label: \"Label\",\n value: node.label,\n help: \"Add a step label.\",\n fixed: true,\n onchange: function(new_label) {\n var duplicate = false;\n for (var i in workflow.nodes) {\n var n = workflow.nodes[i];\n if (n.label && n.label == new_label && n.id != node.id) {\n duplicate = true;\n break;\n }\n }\n var input_id = form.data.match(\"__label\");\n var input_element = form.element_list[input_id];\n input_element.model.set(\n \"error_text\",\n duplicate && \"Duplicate label. Please fix this before saving the workflow.\"\n );\n form.trigger(\"change\");\n }\n });\n}\n\n/** Builds all sub sections */\nfunction _addSections(form) {\n var options = form.model.attributes;\n var inputs = options.inputs;\n var datatypes = options.datatypes;\n var node = options.node;\n var workflow = options.workflow;\n var post_job_actions = node.post_job_actions;\n var output_id = node.output_terminals && Object.keys(node.output_terminals)[0];\n\n /** Visit input nodes and enrich by name/value pairs from server data */\n function visit(head, head_list) {\n head_list = head_list || [];\n head_list.push(head);\n for (var i in head.inputs) {\n var input = head.inputs[i];\n var action = input.action;\n if (action) {\n input.name = `pja__${output_id}__${input.action}`;\n if (input.pja_arg) {\n input.name += `__${input.pja_arg}`;\n }\n if (input.payload) {\n for (var p_id in input.payload) {\n input.payload[`${input.name}__${p_id}`] = input.payload[p_id];\n delete input.payload[p_id];\n }\n }\n var d = post_job_actions[input.action + output_id];\n if (d) {\n for (var j in head_list) {\n head_list[j].expanded = true;\n }\n if (input.pja_arg) {\n input.value = (d.action_arguments && d.action_arguments[input.pja_arg]) || input.value;\n } else {\n input.value = \"true\";\n }\n }\n }\n input.inputs && visit(input, head_list.slice(0));\n }\n }\n\n /** Builds sub section with step actions/annotation */\n function _makeSection(output_id, datatypes) {\n var extensions = [];\n var input_terminal_names = [];\n for (var key in datatypes) {\n extensions.push({ 0: datatypes[key], 1: datatypes[key] });\n }\n for (key in node.input_terminals) {\n input_terminal_names.push(node.input_terminals[key].name);\n }\n extensions.sort((a, b) => (a.label > b.label ? 1 : a.label < b.label ? -1 : 0));\n extensions.unshift({\n 0: \"Sequences\",\n 1: \"Sequences\"\n });\n extensions.unshift({\n 0: \"Roadmaps\",\n 1: \"Roadmaps\"\n });\n extensions.unshift({\n 0: \"Leave unchanged\",\n 1: \"__empty__\"\n });\n var output;\n var input_config = {\n title: `Configure Output: '${output_id}'`,\n type: \"section\",\n flat: true,\n inputs: [\n {\n label: \"Label\",\n type: \"text\",\n value: ((output = node.getWorkflowOutput(output_id)) && output.label) || \"\",\n help:\n \"This will provide a short name to describe the output - this must be unique across workflows.\",\n onchange: function(new_value) {\n workflow.attemptUpdateOutputLabel(node, output_id, new_value);\n }\n },\n {\n action: \"RenameDatasetAction\",\n pja_arg: \"newname\",\n label: \"Rename dataset\",\n type: \"text\",\n value: \"\",\n ignore: \"\",\n help: `This action will rename the output dataset. Click here for more information. Valid inputs are: ${input_terminal_names.join(\n \", \"\n )}.`\n },\n {\n action: \"ChangeDatatypeAction\",\n pja_arg: \"newtype\",\n label: \"Change datatype\",\n type: \"select\",\n ignore: \"__empty__\",\n value: \"__empty__\",\n options: extensions,\n help: \"This action will change the datatype of the output to the indicated value.\"\n },\n {\n action: \"TagDatasetAction\",\n pja_arg: \"tags\",\n label: \"Add Tags\",\n type: \"text\",\n value: \"\",\n ignore: \"\",\n help: \"This action will set tags for the dataset.\"\n },\n {\n action: \"RemoveTagDatasetAction\",\n pja_arg: \"tags\",\n label: \"Remove Tags\",\n type: \"text\",\n value: \"\",\n ignore: \"\",\n help: \"This action will remove tags for the dataset.\"\n },\n {\n title: \"Assign columns\",\n type: \"section\",\n flat: true,\n inputs: [\n {\n action: \"ColumnSetAction\",\n pja_arg: \"chromCol\",\n label: \"Chrom column\",\n type: \"integer\",\n value: \"\",\n ignore: \"\"\n },\n {\n action: \"ColumnSetAction\",\n pja_arg: \"startCol\",\n label: \"Start column\",\n type: \"integer\",\n value: \"\",\n ignore: \"\"\n },\n {\n action: \"ColumnSetAction\",\n pja_arg: \"endCol\",\n label: \"End column\",\n type: \"integer\",\n value: \"\",\n ignore: \"\"\n },\n {\n action: \"ColumnSetAction\",\n pja_arg: \"strandCol\",\n label: \"Strand column\",\n type: \"integer\",\n value: \"\",\n ignore: \"\"\n },\n {\n action: \"ColumnSetAction\",\n pja_arg: \"nameCol\",\n label: \"Name column\",\n type: \"integer\",\n value: \"\",\n ignore: \"\"\n }\n ],\n help: \"This action will set column assignments in the output dataset. Blank fields are ignored.\"\n }\n ]\n };\n visit(input_config);\n return input_config;\n }\n\n if (output_id) {\n inputs.push({\n name: `pja__${output_id}__EmailAction`,\n label: \"Email notification\",\n type: \"boolean\",\n value: String(Boolean(post_job_actions[`EmailAction${output_id}`])),\n ignore: \"false\",\n help: \"An email notification will be sent when the job has completed.\",\n payload: {\n host: window.location.host\n }\n });\n inputs.push({\n name: `pja__${output_id}__DeleteIntermediatesAction`,\n label: \"Output cleanup\",\n type: \"boolean\",\n value: String(Boolean(post_job_actions[`DeleteIntermediatesAction${output_id}`])),\n ignore: \"false\",\n help:\n \"Upon completion of this step, delete non-starred outputs from completed workflow steps if they are no longer required as inputs.\"\n });\n for (var i in node.output_terminals) {\n inputs.push(_makeSection(i, datatypes));\n }\n }\n}\n\nexport default {\n Default: Default,\n Tool: Tool\n};\n"]} \ No newline at end of file +{"version":3,"sources":["mvc/workflow/workflow-forms.js"],"names":["_addLabelAnnotation","deepeach","options","form","input","type","test_param","node","inputs","unshift","_addSections","label","fixed","value","annotation","area","help","workflow","name","i","nodes","n","new_label","id","duplicate","data","match","element_list","input_id","model","set","trigger","_visit","head","input_element","post_job_actions","push","action","head_list","pja_arg","payload","p_id","d","expanded","action_arguments","output_id","_makeSection","extensions","datatypes","key","1","input_terminal_names","b","a","0","output","input_config","flat","getWorkflowOutput","new_value","title","onchange","join","ignore","attributes","output_terminals","Object","keys","host","String","Boolean","location","Default","Backbone","View","extend","initialize","self","this","_formView2","default","_utils2","merge","request","url","Galaxy","root","content_id","create","update_field_data","success","_toolFormBase2","text_enable","text_disable","initial_errors","cls","initialmodel","process","_customize","resolve","get","postchange","tool_id","version","$","current_state","buildmodel","config_form","tool_version","emit","debug","response","error","indexOf","info","textify","__class__","collapsible_value","is_workflow","length","undefined","Tool"],"mappings":"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","file":"../../../scripts/mvc/workflow/workflow-forms.js","sourcesContent":["import Utils from \"utils/utils\";\nimport Form from \"mvc/form/form-view\";\nimport ToolFormBase from \"mvc/tool/tool-form-base\";\n/** Default form wrapper for non-tool modules in the workflow editor. */\nvar Default = Backbone.View.extend({\n initialize: function(options) {\n var self = this;\n var node = options.node;\n this.form = new Form(\n Utils.merge(options, {\n onchange: function() {\n Utils.request({\n type: \"POST\",\n url: `${Galaxy.root}api/workflows/build_module`,\n data: {\n id: node.id,\n type: node.type,\n content_id: node.content_id,\n inputs: self.form.data.create()\n },\n success: function(data) {\n node.update_field_data(data);\n }\n });\n }\n })\n );\n _addLabelAnnotation(this.form);\n this.form.render();\n }\n});\n\n/** Tool form wrapper for the workflow editor. */\nvar Tool = Backbone.View.extend({\n initialize: function(options) {\n var self = this;\n var node = options.node;\n this.form = new ToolFormBase(\n Utils.merge(options, {\n text_enable: \"Set in Advance\",\n text_disable: \"Set at Runtime\",\n narrow: true,\n initial_errors: true,\n cls: \"ui-portlet-narrow\",\n initialmodel: function(process, form) {\n self._customize(form);\n process.resolve();\n },\n buildmodel: function(process, form) {\n form.model.get(\"postchange\")(process, form);\n },\n postchange: function(process, form) {\n var options = form.model.attributes;\n var current_state = {\n tool_id: options.id,\n tool_version: options.version,\n type: \"tool\",\n inputs: $.extend(true, {}, form.data.create())\n };\n Galaxy.emit.debug(\"tool-form-workflow::postchange()\", \"Sending current state.\", current_state);\n Utils.request({\n type: \"POST\",\n url: `${Galaxy.root}api/workflows/build_module`,\n data: current_state,\n success: function(data) {\n form.model.set(data.config_form);\n self._customize(form);\n form.update(data.config_form);\n form.errors(data.config_form);\n // This hasn't modified the workflow, just returned\n // module information for the tool to update the workflow\n // state stored on the client with. User needs to save\n // for this to take effect.\n node.update_field_data(data);\n Galaxy.emit.debug(\"tool-form-workflow::postchange()\", \"Received new model.\", data);\n process.resolve();\n },\n error: function(response) {\n Galaxy.emit.debug(\"tool-form-workflow::postchange()\", \"Refresh request failed.\", response);\n process.reject();\n }\n });\n }\n })\n );\n },\n\n _customize: function(form) {\n var options = form.model.attributes;\n Utils.deepeach(options.inputs, input => {\n if (input.type) {\n if ([\"data\", \"data_collection\"].indexOf(input.type) != -1) {\n input.type = \"hidden\";\n input.info = `Data input '${input.name}' (${Utils.textify(input.extensions)})`;\n input.value = { __class__: \"RuntimeValue\" };\n } else if (!input.fixed) {\n input.collapsible_value = {\n __class__: \"RuntimeValue\"\n };\n input.is_workflow =\n (input.options && input.options.length === 0) || [\"integer\", \"float\"].indexOf(input.type) != -1;\n }\n }\n });\n Utils.deepeach(options.inputs, input => {\n if (input.type === \"conditional\") {\n input.test_param.collapsible_value = undefined;\n }\n });\n _addSections(form);\n _addLabelAnnotation(form);\n }\n});\n\n/** Augments the module form definition by adding label and annotation fields */\nfunction _addLabelAnnotation(form) {\n var options = form.model.attributes;\n var workflow = options.workflow;\n var node = options.node;\n options.inputs.unshift({\n type: \"text\",\n name: \"__annotation\",\n label: \"Annotation\",\n fixed: true,\n value: node.annotation,\n area: true,\n help: \"Add an annotation or notes to this step. Annotations are available when a workflow is viewed.\"\n });\n options.inputs.unshift({\n type: \"text\",\n name: \"__label\",\n label: \"Label\",\n value: node.label,\n help: \"Add a step label.\",\n fixed: true,\n onchange: function(new_label) {\n var duplicate = false;\n for (var i in workflow.nodes) {\n var n = workflow.nodes[i];\n if (n.label && n.label == new_label && n.id != node.id) {\n duplicate = true;\n break;\n }\n }\n var input_id = form.data.match(\"__label\");\n var input_element = form.element_list[input_id];\n input_element.model.set(\n \"error_text\",\n duplicate && \"Duplicate label. Please fix this before saving the workflow.\"\n );\n form.trigger(\"change\");\n }\n });\n}\n\n/** Visit input nodes and enrich by name/value pairs from server data */\nfunction _visit(head, head_list, output_id, options) {\n var post_job_actions = options.node.post_job_actions;\n head_list = head_list || [];\n head_list.push(head);\n for (var i in head.inputs) {\n var input = head.inputs[i];\n var action = input.action;\n if (action) {\n input.name = `pja__${output_id}__${input.action}`;\n if (input.pja_arg) {\n input.name += `__${input.pja_arg}`;\n }\n if (input.payload) {\n for (var p_id in input.payload) {\n input.payload[`${input.name}__${p_id}`] = input.payload[p_id];\n delete input.payload[p_id];\n }\n }\n var d = post_job_actions[input.action + output_id];\n if (d) {\n for (var j in head_list) {\n head_list[j].expanded = true;\n }\n if (input.pja_arg) {\n input.value = (d.action_arguments && d.action_arguments[input.pja_arg]) || input.value;\n } else {\n input.value = \"true\";\n }\n }\n }\n if (input.inputs) {\n _visit(input, head_list.slice(0), output_id, options);\n }\n }\n}\n\n/** Builds sub section with step actions/annotation */\nfunction _makeSection(output_id, options) {\n var extensions = [];\n var input_terminal_names = [];\n var datatypes = options.datatypes;\n var node = options.node;\n var workflow = options.workflow;\n\n for (var key in datatypes) {\n extensions.push({ 0: datatypes[key], 1: datatypes[key] });\n }\n for (key in node.input_terminals) {\n input_terminal_names.push(node.input_terminals[key].name);\n }\n extensions.sort((a, b) => (a.label > b.label ? 1 : a.label < b.label ? -1 : 0));\n extensions.unshift({\n 0: \"Sequences\",\n 1: \"Sequences\"\n });\n extensions.unshift({\n 0: \"Roadmaps\",\n 1: \"Roadmaps\"\n });\n extensions.unshift({\n 0: \"Leave unchanged\",\n 1: \"__empty__\"\n });\n var output;\n var input_config = {\n title: `Configure Output: '${output_id}'`,\n type: \"section\",\n flat: true,\n inputs: [\n {\n label: \"Label\",\n type: \"text\",\n value: ((output = node.getWorkflowOutput(output_id)) && output.label) || \"\",\n help: \"This will provide a short name to describe the output - this must be unique across workflows.\",\n onchange: function(new_value) {\n workflow.attemptUpdateOutputLabel(node, output_id, new_value);\n }\n },\n {\n action: \"RenameDatasetAction\",\n pja_arg: \"newname\",\n label: \"Rename dataset\",\n type: \"text\",\n value: \"\",\n ignore: \"\",\n help: `This action will rename the output dataset. Click here for more information. Valid inputs are: ${input_terminal_names.join(\n \", \"\n )}.`\n },\n {\n action: \"ChangeDatatypeAction\",\n pja_arg: \"newtype\",\n label: \"Change datatype\",\n type: \"select\",\n ignore: \"__empty__\",\n value: \"__empty__\",\n options: extensions,\n help: \"This action will change the datatype of the output to the indicated value.\"\n },\n {\n action: \"TagDatasetAction\",\n pja_arg: \"tags\",\n label: \"Add Tags\",\n type: \"text\",\n value: \"\",\n ignore: \"\",\n help: \"This action will set tags for the dataset.\"\n },\n {\n action: \"RemoveTagDatasetAction\",\n pja_arg: \"tags\",\n label: \"Remove Tags\",\n type: \"text\",\n value: \"\",\n ignore: \"\",\n help: \"This action will remove tags for the dataset.\"\n },\n {\n title: \"Assign columns\",\n type: \"section\",\n flat: true,\n inputs: [\n {\n action: \"ColumnSetAction\",\n pja_arg: \"chromCol\",\n label: \"Chrom column\",\n type: \"integer\",\n value: \"\",\n ignore: \"\"\n },\n {\n action: \"ColumnSetAction\",\n pja_arg: \"startCol\",\n label: \"Start column\",\n type: \"integer\",\n value: \"\",\n ignore: \"\"\n },\n {\n action: \"ColumnSetAction\",\n pja_arg: \"endCol\",\n label: \"End column\",\n type: \"integer\",\n value: \"\",\n ignore: \"\"\n },\n {\n action: \"ColumnSetAction\",\n pja_arg: \"strandCol\",\n label: \"Strand column\",\n type: \"integer\",\n value: \"\",\n ignore: \"\"\n },\n {\n action: \"ColumnSetAction\",\n pja_arg: \"nameCol\",\n label: \"Name column\",\n type: \"integer\",\n value: \"\",\n ignore: \"\"\n }\n ],\n help: \"This action will set column assignments in the output dataset. Blank fields are ignored.\"\n }\n ]\n };\n _visit(input_config, [], output_id, options);\n return input_config;\n}\n\n/** Builds all sub sections */\nfunction _addSections(form) {\n var options = form.model.attributes;\n var inputs = options.inputs;\n var node = options.node;\n var post_job_actions = node.post_job_actions;\n var output_id = node.output_terminals && Object.keys(node.output_terminals)[0];\n\n if (output_id) {\n inputs.push({\n name: `pja__${output_id}__EmailAction`,\n label: \"Email notification\",\n type: \"boolean\",\n value: String(Boolean(post_job_actions[`EmailAction${output_id}`])),\n ignore: \"false\",\n help: \"An email notification will be sent when the job has completed.\",\n payload: {\n host: window.location.host\n }\n });\n inputs.push({\n name: `pja__${output_id}__DeleteIntermediatesAction`,\n label: \"Output cleanup\",\n type: \"boolean\",\n value: String(Boolean(post_job_actions[`DeleteIntermediatesAction${output_id}`])),\n ignore: \"false\",\n help:\n \"Upon completion of this step, delete non-starred outputs from completed workflow steps if they are no longer required as inputs.\"\n });\n for (var i in node.output_terminals) {\n inputs.push(_makeSection(i, options));\n }\n }\n}\n\nexport default {\n Default: Default,\n Tool: Tool\n};\n"]} \ No newline at end of file diff --git a/static/maps/mvc/workflow/workflow-node.js.map b/static/maps/mvc/workflow/workflow-node.js.map index afff34177b71..8252b1ff8638 100644 --- a/static/maps/mvc/workflow/workflow-node.js.map +++ b/static/maps/mvc/workflow/workflow-node.js.map @@ -1 +1 @@ -{"version":3,"sources":["mvc/workflow/workflow-node.js"],"names":["Node","Backbone","Model","extend","initialize","app","attr","this","element","input_terminals","output_terminals","errors","workflow_outputs","getWorkflowOutput","outputName","_","findWhere","output_name","isWorkflowOutput","undefined","removeWorkflowOutput","splice","addWorkflowOutput","label","output","push","labelWorkflowOutput","changed","oldLabel","workflowOutput","workflow","updateOutputLabel","markChanged","connectedOutputTerminals","connectedTerminals","t","connectors","length","hasConnectedOutputTerminals","_connectedTerminals","outputTerminals","connectedMappedInputTerminals","_connectedMappedTerminals","hasConnectedMappedInputTerminals","inputTerminals","inputTerminal","isMappedOver","terminals","mapped_outputs","$","each","isCollection","mappedInputTerminals","_mappedTerminals","mapOver","mappedTerminals","hasMappedOverInputTerminals","found","redraw","destroy","k","remove","addClass","make_inactive","get","p","parentNode","make_active","data","type","name","config_form","tool_version","version","tool_state","removeChild","appendChild","tooltip","annotation","post_job_actions","removeClass","uuid","init_field_data","node","nodeView","el","data_outputs","i","update_field_data","data_inputs","unused_outputs","addDataOutput","cur_name","output_view","cur_name_in_data_outputs","data_names","data_name","terminalElement","terminal","x","outputViews","unused_output","wf_output","extensions","pja_in","old_body","new_body","newTerminalViews","input","terminalView","addDataInput","difference","values","terminalViews","unusedView","replaceWith","error","text","b","find","tmp","node_changed"],"mappings":"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","file":"../../../scripts/mvc/workflow/workflow-node.js","sourcesContent":["import NodeView from \"mvc/workflow/workflow-view-node\";\nvar Node = Backbone.Model.extend({\n initialize: function(app, attr) {\n this.app = app;\n this.element = attr.element;\n this.input_terminals = {};\n this.output_terminals = {};\n this.errors = {};\n this.workflow_outputs = [];\n },\n getWorkflowOutput: function(outputName) {\n return _.findWhere(this.workflow_outputs, {\n output_name: outputName\n });\n },\n isWorkflowOutput: function(outputName) {\n return this.getWorkflowOutput(outputName) != undefined;\n },\n removeWorkflowOutput: function(outputName) {\n while (this.isWorkflowOutput(outputName)) {\n this.workflow_outputs.splice(this.getWorkflowOutput(outputName), 1);\n }\n },\n addWorkflowOutput: function(outputName, label) {\n if (!this.isWorkflowOutput(outputName)) {\n var output = { output_name: outputName };\n if (label) {\n output[\"label\"] = label;\n }\n this.workflow_outputs.push(output);\n return true;\n }\n return false;\n },\n labelWorkflowOutput: function(outputName, label) {\n var changed = false;\n var oldLabel = null;\n if (this.isWorkflowOutput(outputName)) {\n var workflowOutput = this.getWorkflowOutput(outputName);\n oldLabel = workflowOutput[\"label\"];\n workflowOutput[\"label\"] = label;\n changed = oldLabel != label;\n } else {\n changed = this.addWorkflowOutput(outputName, label);\n }\n if (changed) {\n this.app.workflow.updateOutputLabel(oldLabel, label);\n this.markChanged();\n this.nodeView.redrawWorkflowOutputs();\n }\n return changed;\n },\n connectedOutputTerminals: function() {\n return this._connectedTerminals(this.output_terminals);\n },\n _connectedTerminals: function(terminals) {\n var connectedTerminals = [];\n $.each(terminals, (_, t) => {\n if (t.connectors.length > 0) {\n connectedTerminals.push(t);\n }\n });\n return connectedTerminals;\n },\n hasConnectedOutputTerminals: function() {\n // return this.connectedOutputTerminals().length > 0; <- optimized this\n var outputTerminals = this.output_terminals;\n for (var outputName in outputTerminals) {\n if (outputTerminals[outputName].connectors.length > 0) {\n return true;\n }\n }\n return false;\n },\n connectedMappedInputTerminals: function() {\n return this._connectedMappedTerminals(this.input_terminals);\n },\n hasConnectedMappedInputTerminals: function() {\n // return this.connectedMappedInputTerminals().length > 0; <- optimized this\n var inputTerminals = this.input_terminals;\n for (var inputName in inputTerminals) {\n var inputTerminal = inputTerminals[inputName];\n if (inputTerminal.connectors.length > 0 && inputTerminal.isMappedOver()) {\n return true;\n }\n }\n return false;\n },\n _connectedMappedTerminals: function(terminals) {\n var mapped_outputs = [];\n $.each(terminals, (_, t) => {\n var mapOver = t.mapOver();\n if (mapOver.isCollection) {\n if (t.connectors.length > 0) {\n mapped_outputs.push(t);\n }\n }\n });\n return mapped_outputs;\n },\n mappedInputTerminals: function() {\n return this._mappedTerminals(this.input_terminals);\n },\n _mappedTerminals: function(terminals) {\n var mappedTerminals = [];\n $.each(terminals, (_, t) => {\n var mapOver = t.mapOver();\n if (mapOver.isCollection) {\n mappedTerminals.push(t);\n }\n });\n return mappedTerminals;\n },\n hasMappedOverInputTerminals: function() {\n var found = false;\n _.each(this.input_terminals, t => {\n var mapOver = t.mapOver();\n if (mapOver.isCollection) {\n found = true;\n }\n });\n return found;\n },\n redraw: function() {\n $.each(this.input_terminals, (_, t) => {\n t.redraw();\n });\n $.each(this.output_terminals, (_, t) => {\n t.redraw();\n });\n },\n destroy: function() {\n $.each(this.input_terminals, (k, t) => {\n t.destroy();\n });\n $.each(this.output_terminals, (k, t) => {\n t.destroy();\n });\n this.app.workflow.remove_node(this);\n $(this.element).remove();\n },\n make_active: function() {\n $(this.element).addClass(\"toolForm-active\");\n },\n make_inactive: function() {\n // Keep inactive nodes stacked from most to least recently active\n // by moving element to the end of parent's node list\n var element = this.element.get(0);\n (p => {\n p.removeChild(element);\n p.appendChild(element);\n })(element.parentNode);\n // Remove active class\n $(element).removeClass(\"toolForm-active\");\n },\n init_field_data: function(data) {\n if (data.type) {\n this.type = data.type;\n }\n this.name = data.name;\n this.config_form = data.config_form;\n this.tool_version = this.config_form && this.config_form.version;\n this.tool_state = data.tool_state;\n this.errors = data.errors;\n this.tooltip = data.tooltip ? data.tooltip : \"\";\n this.annotation = data.annotation;\n this.post_job_actions = data.post_job_actions ? data.post_job_actions : {};\n this.label = data.label;\n this.uuid = data.uuid;\n this.workflow_outputs = data.workflow_outputs ? data.workflow_outputs : [];\n var node = this;\n var nodeView = new NodeView({\n el: this.element[0],\n node: node\n });\n node.nodeView = nodeView;\n $.each(data.data_inputs, (i, input) => {\n nodeView.addDataInput(input);\n });\n if (data.data_inputs.length > 0 && data.data_outputs.length > 0) {\n nodeView.addRule();\n }\n $.each(data.data_outputs, (i, output) => {\n nodeView.addDataOutput(output);\n });\n nodeView.render();\n this.app.workflow.node_changed(this, true);\n },\n update_field_data: function(data) {\n var node = this;\n var nodeView = node.nodeView;\n // remove unused output views and remove pre-existing output views from data.data_outputs,\n // so that these are not added twice.\n var unused_outputs = [];\n // nodeView.outputViews contains pre-existing outputs,\n // while data.data_output contains what should be displayed.\n // Now we gather the unused outputs\n $.each(nodeView.outputViews, (i, output_view) => {\n var cur_name = output_view.output.name;\n var data_names = data.data_outputs;\n var cur_name_in_data_outputs = false;\n _.each(data_names, data_name => {\n if (data_name.name == cur_name) {\n cur_name_in_data_outputs = true;\n }\n });\n if (cur_name_in_data_outputs === false) {\n unused_outputs.push(cur_name);\n }\n });\n\n // Remove the unused outputs\n _.each(unused_outputs, unused_output => {\n _.each(nodeView.outputViews[unused_output].terminalElement.terminal.connectors, x => {\n if (x) {\n x.destroy(); // Removes the noodle connectors\n }\n });\n nodeView.outputViews[unused_output].remove(); // removes the rendered output\n delete nodeView.outputViews[unused_output]; // removes the reference to the output\n delete node.output_terminals[unused_output]; // removes the output terminal\n });\n $.each(node.workflow_outputs, (i, wf_output) => {\n if (wf_output && !node.output_terminals[wf_output.output_name]) {\n node.workflow_outputs.splice(i, 1); // removes output from list of workflow outputs\n }\n });\n $.each(data.data_outputs, (i, output) => {\n if (!nodeView.outputViews[output.name]) {\n nodeView.addDataOutput(output); // add data output if it does not yet exist\n } else {\n // the output already exists, but the output formats may have changed.\n // Therefore we update the datatypes and destroy invalid connections.\n node.output_terminals[output.name].datatypes = output.extensions;\n node.output_terminals[output.name].destroyInvalidConnections();\n }\n });\n this.tool_state = data.tool_state;\n this.config_form = data.config_form;\n this.tool_version = this.config_form && this.config_form.version;\n this.errors = data.errors;\n this.annotation = data[\"annotation\"];\n this.label = data.label;\n if (\"post_job_actions\" in data) {\n // Won't be present in response for data inputs\n var pja_in = data.post_job_actions;\n this.post_job_actions = pja_in ? pja_in : {};\n }\n node.nodeView.renderToolErrors();\n // Update input rows\n var old_body = nodeView.$(\"div.inputs\");\n var new_body = nodeView.newInputsDiv();\n var newTerminalViews = {};\n _.each(data.data_inputs, input => {\n var terminalView = node.nodeView.addDataInput(input, new_body);\n newTerminalViews[input.name] = terminalView;\n });\n // Cleanup any leftover terminals\n _.each(_.difference(_.values(nodeView.terminalViews), _.values(newTerminalViews)), unusedView => {\n unusedView.el.terminal.destroy();\n });\n nodeView.terminalViews = newTerminalViews;\n node.nodeView.render();\n // In general workflow editor assumes tool outputs don't change in # or\n // type (not really valid right?) but adding special logic here for\n // data collection input parameters that can have their collection\n // change.\n if (data.data_outputs.length == 1 && \"collection_type\" in data.data_outputs[0]) {\n nodeView.updateDataOutput(data.data_outputs[0]);\n }\n old_body.replaceWith(new_body);\n if (\"workflow_outputs\" in data) {\n // Won't be present in response for data inputs\n this.workflow_outputs = workflow_outputs ? workflow_outputs : [];\n }\n // If active, reactivate with new config_form\n this.markChanged();\n this.redraw();\n },\n error: function(text) {\n var b = $(this.element).find(\".toolFormBody\");\n b.find(\"div\").remove();\n var tmp = `
${text}
`;\n this.config_form = tmp;\n b.html(tmp);\n this.app.workflow.node_changed(this);\n },\n markChanged: function() {\n this.app.workflow.node_changed(this);\n }\n});\nexport default Node;\n"]} \ No newline at end of file +{"version":3,"sources":["mvc/workflow/workflow-node.js"],"names":["Node","Backbone","Model","extend","initialize","app","attr","this","element","input_terminals","output_terminals","errors","workflow_outputs","getWorkflowOutput","outputName","_","findWhere","output_name","isWorkflowOutput","undefined","removeWorkflowOutput","splice","addWorkflowOutput","label","output","push","labelWorkflowOutput","changed","oldLabel","workflowOutput","workflow","updateOutputLabel","markChanged","connectedOutputTerminals","connectedTerminals","t","connectors","length","hasConnectedOutputTerminals","_connectedTerminals","outputTerminals","connectedMappedInputTerminals","_connectedMappedTerminals","hasConnectedMappedInputTerminals","inputTerminals","inputTerminal","isMappedOver","terminals","mapped_outputs","$","each","isCollection","mappedInputTerminals","_mappedTerminals","mapOver","mappedTerminals","hasMappedOverInputTerminals","found","redraw","destroy","k","remove","addClass","make_inactive","get","p","parentNode","make_active","data","type","name","config_form","tool_version","version","tool_state","removeChild","appendChild","tooltip","annotation","post_job_actions","removeClass","uuid","init_field_data","node","nodeView","el","data_outputs","i","update_field_data","data_inputs","unused_outputs","addDataOutput","cur_name","output_view","cur_name_in_data_outputs","data_names","data_name","terminalElement","terminal","x","outputViews","unused_output","wf_output","extensions","pja_in","old_body","new_body","newTerminalViews","input","terminalView","addDataInput","difference","values","terminalViews","unusedView","replaceWith","error","text","b","find","tmp","node_changed"],"mappings":"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","file":"../../../scripts/mvc/workflow/workflow-node.js","sourcesContent":["import NodeView from \"mvc/workflow/workflow-view-node\";\nvar Node = Backbone.Model.extend({\n initialize: function(app, attr) {\n this.app = app;\n this.element = attr.element;\n this.input_terminals = {};\n this.output_terminals = {};\n this.errors = {};\n this.workflow_outputs = [];\n },\n getWorkflowOutput: function(outputName) {\n return _.findWhere(this.workflow_outputs, {\n output_name: outputName\n });\n },\n isWorkflowOutput: function(outputName) {\n return this.getWorkflowOutput(outputName) !== undefined;\n },\n removeWorkflowOutput: function(outputName) {\n while (this.isWorkflowOutput(outputName)) {\n this.workflow_outputs.splice(this.getWorkflowOutput(outputName), 1);\n }\n },\n addWorkflowOutput: function(outputName, label) {\n if (!this.isWorkflowOutput(outputName)) {\n var output = { output_name: outputName };\n if (label) {\n output.label = label;\n }\n this.workflow_outputs.push(output);\n return true;\n }\n return false;\n },\n labelWorkflowOutput: function(outputName, label) {\n var changed = false;\n var oldLabel = null;\n if (this.isWorkflowOutput(outputName)) {\n var workflowOutput = this.getWorkflowOutput(outputName);\n oldLabel = workflowOutput.label;\n workflowOutput.label = label;\n changed = oldLabel != label;\n } else {\n changed = this.addWorkflowOutput(outputName, label);\n }\n if (changed) {\n this.app.workflow.updateOutputLabel(oldLabel, label);\n this.markChanged();\n this.nodeView.redrawWorkflowOutputs();\n }\n return changed;\n },\n connectedOutputTerminals: function() {\n return this._connectedTerminals(this.output_terminals);\n },\n _connectedTerminals: function(terminals) {\n var connectedTerminals = [];\n $.each(terminals, (_, t) => {\n if (t.connectors.length > 0) {\n connectedTerminals.push(t);\n }\n });\n return connectedTerminals;\n },\n hasConnectedOutputTerminals: function() {\n // return this.connectedOutputTerminals().length > 0; <- optimized this\n var outputTerminals = this.output_terminals;\n for (var outputName in outputTerminals) {\n if (outputTerminals[outputName].connectors.length > 0) {\n return true;\n }\n }\n return false;\n },\n connectedMappedInputTerminals: function() {\n return this._connectedMappedTerminals(this.input_terminals);\n },\n hasConnectedMappedInputTerminals: function() {\n // return this.connectedMappedInputTerminals().length > 0; <- optimized this\n var inputTerminals = this.input_terminals;\n for (var inputName in inputTerminals) {\n var inputTerminal = inputTerminals[inputName];\n if (inputTerminal.connectors.length > 0 && inputTerminal.isMappedOver()) {\n return true;\n }\n }\n return false;\n },\n _connectedMappedTerminals: function(terminals) {\n var mapped_outputs = [];\n $.each(terminals, (_, t) => {\n var mapOver = t.mapOver();\n if (mapOver.isCollection) {\n if (t.connectors.length > 0) {\n mapped_outputs.push(t);\n }\n }\n });\n return mapped_outputs;\n },\n mappedInputTerminals: function() {\n return this._mappedTerminals(this.input_terminals);\n },\n _mappedTerminals: function(terminals) {\n var mappedTerminals = [];\n $.each(terminals, (_, t) => {\n var mapOver = t.mapOver();\n if (mapOver.isCollection) {\n mappedTerminals.push(t);\n }\n });\n return mappedTerminals;\n },\n hasMappedOverInputTerminals: function() {\n var found = false;\n _.each(this.input_terminals, t => {\n var mapOver = t.mapOver();\n if (mapOver.isCollection) {\n found = true;\n }\n });\n return found;\n },\n redraw: function() {\n $.each(this.input_terminals, (_, t) => {\n t.redraw();\n });\n $.each(this.output_terminals, (_, t) => {\n t.redraw();\n });\n },\n destroy: function() {\n $.each(this.input_terminals, (k, t) => {\n t.destroy();\n });\n $.each(this.output_terminals, (k, t) => {\n t.destroy();\n });\n this.app.workflow.remove_node(this);\n $(this.element).remove();\n },\n make_active: function() {\n $(this.element).addClass(\"toolForm-active\");\n },\n make_inactive: function() {\n // Keep inactive nodes stacked from most to least recently active\n // by moving element to the end of parent's node list\n var element = this.element.get(0);\n (p => {\n p.removeChild(element);\n p.appendChild(element);\n })(element.parentNode);\n // Remove active class\n $(element).removeClass(\"toolForm-active\");\n },\n init_field_data: function(data) {\n if (data.type) {\n this.type = data.type;\n }\n this.name = data.name;\n this.config_form = data.config_form;\n this.tool_version = this.config_form && this.config_form.version;\n this.tool_state = data.tool_state;\n this.errors = data.errors;\n this.tooltip = data.tooltip ? data.tooltip : \"\";\n this.annotation = data.annotation;\n this.post_job_actions = data.post_job_actions ? data.post_job_actions : {};\n this.label = data.label;\n this.uuid = data.uuid;\n this.workflow_outputs = data.workflow_outputs ? data.workflow_outputs : [];\n var node = this;\n var nodeView = new NodeView({\n el: this.element[0],\n node: node\n });\n node.nodeView = nodeView;\n $.each(data.data_inputs, (i, input) => {\n nodeView.addDataInput(input);\n });\n if (data.data_inputs.length > 0 && data.data_outputs.length > 0) {\n nodeView.addRule();\n }\n $.each(data.data_outputs, (i, output) => {\n nodeView.addDataOutput(output);\n });\n nodeView.render();\n this.app.workflow.node_changed(this, true);\n },\n update_field_data: function(data) {\n var node = this;\n var nodeView = node.nodeView;\n // remove unused output views and remove pre-existing output views from data.data_outputs,\n // so that these are not added twice.\n var unused_outputs = [];\n // nodeView.outputViews contains pre-existing outputs,\n // while data.data_output contains what should be displayed.\n // Now we gather the unused outputs\n $.each(nodeView.outputViews, (i, output_view) => {\n var cur_name = output_view.output.name;\n var data_names = data.data_outputs;\n var cur_name_in_data_outputs = false;\n _.each(data_names, data_name => {\n if (data_name.name == cur_name) {\n cur_name_in_data_outputs = true;\n }\n });\n if (cur_name_in_data_outputs === false) {\n unused_outputs.push(cur_name);\n }\n });\n\n // Remove the unused outputs\n _.each(unused_outputs, unused_output => {\n _.each(nodeView.outputViews[unused_output].terminalElement.terminal.connectors, x => {\n if (x) {\n x.destroy(); // Removes the noodle connectors\n }\n });\n nodeView.outputViews[unused_output].remove(); // removes the rendered output\n delete nodeView.outputViews[unused_output]; // removes the reference to the output\n delete node.output_terminals[unused_output]; // removes the output terminal\n });\n $.each(node.workflow_outputs, (i, wf_output) => {\n if (wf_output && !node.output_terminals[wf_output.output_name]) {\n node.workflow_outputs.splice(i, 1); // removes output from list of workflow outputs\n }\n });\n $.each(data.data_outputs, (i, output) => {\n if (!nodeView.outputViews[output.name]) {\n nodeView.addDataOutput(output); // add data output if it does not yet exist\n } else {\n // the output already exists, but the output formats may have changed.\n // Therefore we update the datatypes and destroy invalid connections.\n node.output_terminals[output.name].datatypes = output.extensions;\n node.output_terminals[output.name].destroyInvalidConnections();\n }\n });\n this.tool_state = data.tool_state;\n this.config_form = data.config_form;\n this.tool_version = this.config_form && this.config_form.version;\n this.errors = data.errors;\n this.annotation = data.annotation;\n this.label = data.label;\n if (\"post_job_actions\" in data) {\n // Won't be present in response for data inputs\n var pja_in = data.post_job_actions;\n this.post_job_actions = pja_in ? pja_in : {};\n }\n node.nodeView.renderToolErrors();\n // Update input rows\n var old_body = nodeView.$(\"div.inputs\");\n var new_body = nodeView.newInputsDiv();\n var newTerminalViews = {};\n _.each(data.data_inputs, input => {\n var terminalView = node.nodeView.addDataInput(input, new_body);\n newTerminalViews[input.name] = terminalView;\n });\n // Cleanup any leftover terminals\n _.each(_.difference(_.values(nodeView.terminalViews), _.values(newTerminalViews)), unusedView => {\n unusedView.el.terminal.destroy();\n });\n nodeView.terminalViews = newTerminalViews;\n node.nodeView.render();\n // In general workflow editor assumes tool outputs don't change in # or\n // type (not really valid right?) but adding special logic here for\n // data collection input parameters that can have their collection\n // change.\n if (data.data_outputs.length == 1 && \"collection_type\" in data.data_outputs[0]) {\n nodeView.updateDataOutput(data.data_outputs[0]);\n }\n old_body.replaceWith(new_body);\n if (\"workflow_outputs\" in data) {\n // Won't be present in response for data inputs\n this.workflow_outputs = data.workflow_outputs ? data.workflow_outputs : [];\n }\n // If active, reactivate with new config_form\n this.markChanged();\n this.redraw();\n },\n error: function(text) {\n var b = $(this.element).find(\".toolFormBody\");\n b.find(\"div\").remove();\n var tmp = `
${text}
`;\n this.config_form = tmp;\n b.html(tmp);\n this.app.workflow.node_changed(this);\n },\n markChanged: function() {\n this.app.workflow.node_changed(this);\n }\n});\nexport default Node;\n"]} \ No newline at end of file diff --git a/static/scripts/mvc/workflow/workflow-forms.js b/static/scripts/mvc/workflow/workflow-forms.js index f15c5db689dc..1774d6553576 100644 --- a/static/scripts/mvc/workflow/workflow-forms.js +++ b/static/scripts/mvc/workflow/workflow-forms.js @@ -1,2 +1,2 @@ -define("mvc/workflow/workflow-forms",["exports","utils/utils","mvc/form/form-view","mvc/tool/tool-form-base"],function(e,t,a,o){"use strict";function n(e){return e&&e.__esModule?e:{default:e}}function i(e){var t=e.model.attributes,a=t.workflow,o=t.node;t.inputs.unshift({type:"text",name:"__annotation",label:"Annotation",fixed:!0,value:o.annotation,area:!0,help:"Add an annotation or notes to this step. Annotations are available when a workflow is viewed."}),t.inputs.unshift({type:"text",name:"__label",label:"Label",value:o.label,help:"Add a step label.",fixed:!0,onchange:function(t){var n=!1;for(var i in a.nodes){var l=a.nodes[i];if(l.label&&l.label==t&&l.id!=o.id){n=!0;break}}var r=e.data.match("__label");e.element_list[r].model.set("error_text",n&&"Duplicate label. Please fix this before saving the workflow."),e.trigger("change")}})}function l(e){function t(e,a){(a=a||[]).push(e);for(var o in e.inputs){var n=e.inputs[o];if(n.action){if(n.name="pja__"+s+"__"+n.action,n.pja_arg&&(n.name+="__"+n.pja_arg),n.payload)for(var i in n.payload)n.payload[n.name+"__"+i]=n.payload[i],delete n.payload[i];var l=r[n.action+s];if(l){for(var u in a)a[u].expanded=!0;n.pja_arg?n.value=l.action_arguments&&l.action_arguments[n.pja_arg]||n.value:n.value="true"}}n.inputs&&t(n,a.slice(0))}}var a=e.model.attributes,o=a.inputs,n=a.datatypes,i=a.node,l=a.workflow,r=i.post_job_actions,s=i.output_terminals&&Object.keys(i.output_terminals)[0];if(s){o.push({name:"pja__"+s+"__EmailAction",label:"Email notification",type:"boolean",value:String(Boolean(r["EmailAction"+s])),ignore:"false",help:"An email notification will be sent when the job has completed.",payload:{host:window.location.host}}),o.push({name:"pja__"+s+"__DeleteIntermediatesAction",label:"Output cleanup",type:"boolean",value:String(Boolean(r["DeleteIntermediatesAction"+s])),ignore:"false",help:"Upon completion of this step, delete non-starred outputs from completed workflow steps if they are no longer required as inputs."});for(var u in i.output_terminals)o.push(function(e,a){var o=[],n=[];for(var r in a)o.push({0:a[r],1:a[r]});for(r in i.input_terminals)n.push(i.input_terminals[r].name);o.sort(function(e,t){return e.label>t.label?1:e.labelhere for more information. Valid inputs are: '+n.join(", ")+"."},{action:"ChangeDatatypeAction",pja_arg:"newtype",label:"Change datatype",type:"select",ignore:"__empty__",value:"__empty__",options:o,help:"This action will change the datatype of the output to the indicated value."},{action:"TagDatasetAction",pja_arg:"tags",label:"Add Tags",type:"text",value:"",ignore:"",help:"This action will set tags for the dataset."},{action:"RemoveTagDatasetAction",pja_arg:"tags",label:"Remove Tags",type:"text",value:"",ignore:"",help:"This action will remove tags for the dataset."},{title:"Assign columns",type:"section",flat:!0,inputs:[{action:"ColumnSetAction",pja_arg:"chromCol",label:"Chrom column",type:"integer",value:"",ignore:""},{action:"ColumnSetAction",pja_arg:"startCol",label:"Start column",type:"integer",value:"",ignore:""},{action:"ColumnSetAction",pja_arg:"endCol",label:"End column",type:"integer",value:"",ignore:""},{action:"ColumnSetAction",pja_arg:"strandCol",label:"Strand column",type:"integer",value:"",ignore:""},{action:"ColumnSetAction",pja_arg:"nameCol",label:"Name column",type:"integer",value:"",ignore:""}],help:"This action will set column assignments in the output dataset. Blank fields are ignored."}]};return t(u),u}(u,n))}}Object.defineProperty(e,"__esModule",{value:!0});var r=n(t),s=n(a),u=n(o),p=Backbone.View.extend({initialize:function(e){var t=this,a=e.node;this.form=new s.default(r.default.merge(e,{onchange:function(){r.default.request({type:"POST",url:Galaxy.root+"api/workflows/build_module",data:{id:a.id,type:a.type,content_id:a.content_id,inputs:t.form.data.create()},success:function(e){a.update_field_data(e)}})}})),i(this.form),this.form.render()}}),c=Backbone.View.extend({initialize:function(e){var t=this,a=e.node;this.form=new u.default(r.default.merge(e,{text_enable:"Set in Advance",text_disable:"Set at Runtime",narrow:!0,initial_errors:!0,cls:"ui-portlet-narrow",initialmodel:function(e,a){t._customize(a),e.resolve()},buildmodel:function(e,t){t.model.get("postchange")(e,t)},postchange:function(e,o){var n=o.model.attributes,i={tool_id:n.id,tool_version:n.version,type:"tool",inputs:$.extend(!0,{},o.data.create())};Galaxy.emit.debug("tool-form-workflow::postchange()","Sending current state.",i),r.default.request({type:"POST",url:Galaxy.root+"api/workflows/build_module",data:i,success:function(n){o.model.set(n.config_form),t._customize(o),o.update(n.config_form),o.errors(n.config_form),a.update_field_data(n),Galaxy.emit.debug("tool-form-workflow::postchange()","Received new model.",n),e.resolve()},error:function(t){Galaxy.emit.debug("tool-form-workflow::postchange()","Refresh request failed.",t),e.reject()}})}}))},_customize:function(e){var t=e.model.attributes;r.default.deepeach(t.inputs,function(e){e.type&&(-1!=["data","data_collection"].indexOf(e.type)?(e.type="hidden",e.info="Data input '"+e.name+"' ("+r.default.textify(e.extensions)+")",e.value={__class__:"RuntimeValue"}):e.fixed||(e.collapsible_value={__class__:"RuntimeValue"},e.is_workflow=e.options&&0==e.options.length||-1!=["integer","float"].indexOf(e.type)))}),r.default.deepeach(t.inputs,function(e){"conditional"==e.type&&(e.test_param.collapsible_value=void 0)}),l(e),i(e)}});e.default={Default:p,Tool:c}}); +define("mvc/workflow/workflow-forms",["exports","utils/utils","mvc/form/form-view","mvc/tool/tool-form-base"],function(e,t,a,o){"use strict";function n(e){return e&&e.__esModule?e:{default:e}}function i(e){var t=e.model.attributes,a=t.workflow,o=t.node;t.inputs.unshift({type:"text",name:"__annotation",label:"Annotation",fixed:!0,value:o.annotation,area:!0,help:"Add an annotation or notes to this step. Annotations are available when a workflow is viewed."}),t.inputs.unshift({type:"text",name:"__label",label:"Label",value:o.label,help:"Add a step label.",fixed:!0,onchange:function(t){var n=!1;for(var i in a.nodes){var l=a.nodes[i];if(l.label&&l.label==t&&l.id!=o.id){n=!0;break}}var r=e.data.match("__label");e.element_list[r].model.set("error_text",n&&"Duplicate label. Please fix this before saving the workflow."),e.trigger("change")}})}function l(e,t,a,o){var n=o.node.post_job_actions;(t=t||[]).push(e);for(var i in e.inputs){var r=e.inputs[i];if(r.action){if(r.name="pja__"+a+"__"+r.action,r.pja_arg&&(r.name+="__"+r.pja_arg),r.payload)for(var s in r.payload)r.payload[r.name+"__"+s]=r.payload[s],delete r.payload[s];var u=n[r.action+a];if(u){for(var p in t)t[p].expanded=!0;r.pja_arg?r.value=u.action_arguments&&u.action_arguments[r.pja_arg]||r.value:r.value="true"}}r.inputs&&l(r,t.slice(0),a,o)}}function r(e,t){var a=[],o=[],n=t.datatypes,i=t.node,r=t.workflow;for(var s in n)a.push({0:n[s],1:n[s]});for(s in i.input_terminals)o.push(i.input_terminals[s].name);a.sort(function(e,t){return e.label>t.label?1:e.labelhere for more information. Valid inputs are: '+o.join(", ")+"."},{action:"ChangeDatatypeAction",pja_arg:"newtype",label:"Change datatype",type:"select",ignore:"__empty__",value:"__empty__",options:a,help:"This action will change the datatype of the output to the indicated value."},{action:"TagDatasetAction",pja_arg:"tags",label:"Add Tags",type:"text",value:"",ignore:"",help:"This action will set tags for the dataset."},{action:"RemoveTagDatasetAction",pja_arg:"tags",label:"Remove Tags",type:"text",value:"",ignore:"",help:"This action will remove tags for the dataset."},{title:"Assign columns",type:"section",flat:!0,inputs:[{action:"ColumnSetAction",pja_arg:"chromCol",label:"Chrom column",type:"integer",value:"",ignore:""},{action:"ColumnSetAction",pja_arg:"startCol",label:"Start column",type:"integer",value:"",ignore:""},{action:"ColumnSetAction",pja_arg:"endCol",label:"End column",type:"integer",value:"",ignore:""},{action:"ColumnSetAction",pja_arg:"strandCol",label:"Strand column",type:"integer",value:"",ignore:""},{action:"ColumnSetAction",pja_arg:"nameCol",label:"Name column",type:"integer",value:"",ignore:""}],help:"This action will set column assignments in the output dataset. Blank fields are ignored."}]};return l(p,[],e,t),p}function s(e){var t=e.model.attributes,a=t.inputs,o=t.node,n=o.post_job_actions,i=o.output_terminals&&Object.keys(o.output_terminals)[0];if(i){a.push({name:"pja__"+i+"__EmailAction",label:"Email notification",type:"boolean",value:String(Boolean(n["EmailAction"+i])),ignore:"false",help:"An email notification will be sent when the job has completed.",payload:{host:window.location.host}}),a.push({name:"pja__"+i+"__DeleteIntermediatesAction",label:"Output cleanup",type:"boolean",value:String(Boolean(n["DeleteIntermediatesAction"+i])),ignore:"false",help:"Upon completion of this step, delete non-starred outputs from completed workflow steps if they are no longer required as inputs."});for(var l in o.output_terminals)a.push(r(l,t))}}Object.defineProperty(e,"__esModule",{value:!0});var u=n(t),p=n(a),d=n(o),c=Backbone.View.extend({initialize:function(e){var t=this,a=e.node;this.form=new p.default(u.default.merge(e,{onchange:function(){u.default.request({type:"POST",url:Galaxy.root+"api/workflows/build_module",data:{id:a.id,type:a.type,content_id:a.content_id,inputs:t.form.data.create()},success:function(e){a.update_field_data(e)}})}})),i(this.form),this.form.render()}}),f=Backbone.View.extend({initialize:function(e){var t=this,a=e.node;this.form=new d.default(u.default.merge(e,{text_enable:"Set in Advance",text_disable:"Set at Runtime",narrow:!0,initial_errors:!0,cls:"ui-portlet-narrow",initialmodel:function(e,a){t._customize(a),e.resolve()},buildmodel:function(e,t){t.model.get("postchange")(e,t)},postchange:function(e,o){var n=o.model.attributes,i={tool_id:n.id,tool_version:n.version,type:"tool",inputs:$.extend(!0,{},o.data.create())};Galaxy.emit.debug("tool-form-workflow::postchange()","Sending current state.",i),u.default.request({type:"POST",url:Galaxy.root+"api/workflows/build_module",data:i,success:function(n){o.model.set(n.config_form),t._customize(o),o.update(n.config_form),o.errors(n.config_form),a.update_field_data(n),Galaxy.emit.debug("tool-form-workflow::postchange()","Received new model.",n),e.resolve()},error:function(t){Galaxy.emit.debug("tool-form-workflow::postchange()","Refresh request failed.",t),e.reject()}})}}))},_customize:function(e){var t=e.model.attributes;u.default.deepeach(t.inputs,function(e){e.type&&(-1!=["data","data_collection"].indexOf(e.type)?(e.type="hidden",e.info="Data input '"+e.name+"' ("+u.default.textify(e.extensions)+")",e.value={__class__:"RuntimeValue"}):e.fixed||(e.collapsible_value={__class__:"RuntimeValue"},e.is_workflow=e.options&&0===e.options.length||-1!=["integer","float"].indexOf(e.type)))}),u.default.deepeach(t.inputs,function(e){"conditional"===e.type&&(e.test_param.collapsible_value=void 0)}),s(e),i(e)}});e.default={Default:c,Tool:f}}); //# sourceMappingURL=../../../maps/mvc/workflow/workflow-forms.js.map diff --git a/static/scripts/mvc/workflow/workflow-node.js b/static/scripts/mvc/workflow/workflow-node.js index 747c3d6e7e8a..71313055eb71 100644 --- a/static/scripts/mvc/workflow/workflow-node.js +++ b/static/scripts/mvc/workflow/workflow-node.js @@ -1,2 +1,2 @@ -define("mvc/workflow/workflow-node",["exports","mvc/workflow/workflow-view-node"],function(t,e){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=function(t){return t&&t.__esModule?t:{default:t}}(e),n=Backbone.Model.extend({initialize:function(t,e){this.app=t,this.element=e.element,this.input_terminals={},this.output_terminals={},this.errors={},this.workflow_outputs=[]},getWorkflowOutput:function(t){return _.findWhere(this.workflow_outputs,{output_name:t})},isWorkflowOutput:function(t){return void 0!=this.getWorkflowOutput(t)},removeWorkflowOutput:function(t){for(;this.isWorkflowOutput(t);)this.workflow_outputs.splice(this.getWorkflowOutput(t),1)},addWorkflowOutput:function(t,e){if(!this.isWorkflowOutput(t)){var o={output_name:t};return e&&(o.label=e),this.workflow_outputs.push(o),!0}return!1},labelWorkflowOutput:function(t,e){var o=!1,n=null;if(this.isWorkflowOutput(t)){var i=this.getWorkflowOutput(t);n=i.label,i.label=e,o=n!=e}else o=this.addWorkflowOutput(t,e);return o&&(this.app.workflow.updateOutputLabel(n,e),this.markChanged(),this.nodeView.redrawWorkflowOutputs()),o},connectedOutputTerminals:function(){return this._connectedTerminals(this.output_terminals)},_connectedTerminals:function(t){var e=[];return $.each(t,function(t,o){o.connectors.length>0&&e.push(o)}),e},hasConnectedOutputTerminals:function(){var t=this.output_terminals;for(var e in t)if(t[e].connectors.length>0)return!0;return!1},connectedMappedInputTerminals:function(){return this._connectedMappedTerminals(this.input_terminals)},hasConnectedMappedInputTerminals:function(){var t=this.input_terminals;for(var e in t){var o=t[e];if(o.connectors.length>0&&o.isMappedOver())return!0}return!1},_connectedMappedTerminals:function(t){var e=[];return $.each(t,function(t,o){o.mapOver().isCollection&&o.connectors.length>0&&e.push(o)}),e},mappedInputTerminals:function(){return this._mappedTerminals(this.input_terminals)},_mappedTerminals:function(t){var e=[];return $.each(t,function(t,o){o.mapOver().isCollection&&e.push(o)}),e},hasMappedOverInputTerminals:function(){var t=!1;return _.each(this.input_terminals,function(e){e.mapOver().isCollection&&(t=!0)}),t},redraw:function(){$.each(this.input_terminals,function(t,e){e.redraw()}),$.each(this.output_terminals,function(t,e){e.redraw()})},destroy:function(){$.each(this.input_terminals,function(t,e){e.destroy()}),$.each(this.output_terminals,function(t,e){e.destroy()}),this.app.workflow.remove_node(this),$(this.element).remove()},make_active:function(){$(this.element).addClass("toolForm-active")},make_inactive:function(){var t=this.element.get(0);!function(e){e.removeChild(t),e.appendChild(t)}(t.parentNode),$(t).removeClass("toolForm-active")},init_field_data:function(t){t.type&&(this.type=t.type),this.name=t.name,this.config_form=t.config_form,this.tool_version=this.config_form&&this.config_form.version,this.tool_state=t.tool_state,this.errors=t.errors,this.tooltip=t.tooltip?t.tooltip:"",this.annotation=t.annotation,this.post_job_actions=t.post_job_actions?t.post_job_actions:{},this.label=t.label,this.uuid=t.uuid,this.workflow_outputs=t.workflow_outputs?t.workflow_outputs:[];var e=this,n=new o.default({el:this.element[0],node:e});e.nodeView=n,$.each(t.data_inputs,function(t,e){n.addDataInput(e)}),t.data_inputs.length>0&&t.data_outputs.length>0&&n.addRule(),$.each(t.data_outputs,function(t,e){n.addDataOutput(e)}),n.render(),this.app.workflow.node_changed(this,!0)},update_field_data:function(t){var e=this,o=e.nodeView,n=[];if($.each(o.outputViews,function(e,o){var i=o.output.name,r=t.data_outputs,a=!1;_.each(r,function(t){t.name==i&&(a=!0)}),!1===a&&n.push(i)}),_.each(n,function(t){_.each(o.outputViews[t].terminalElement.terminal.connectors,function(t){t&&t.destroy()}),o.outputViews[t].remove(),delete o.outputViews[t],delete e.output_terminals[t]}),$.each(e.workflow_outputs,function(t,o){o&&!e.output_terminals[o.output_name]&&e.workflow_outputs.splice(t,1)}),$.each(t.data_outputs,function(t,n){o.outputViews[n.name]?(e.output_terminals[n.name].datatypes=n.extensions,e.output_terminals[n.name].destroyInvalidConnections()):o.addDataOutput(n)}),this.tool_state=t.tool_state,this.config_form=t.config_form,this.tool_version=this.config_form&&this.config_form.version,this.errors=t.errors,this.annotation=t.annotation,this.label=t.label,"post_job_actions"in t){var i=t.post_job_actions;this.post_job_actions=i||{}}e.nodeView.renderToolErrors();var r=o.$("div.inputs"),a=o.newInputsDiv(),u={};_.each(t.data_inputs,function(t){var o=e.nodeView.addDataInput(t,a);u[t.name]=o}),_.each(_.difference(_.values(o.terminalViews),_.values(u)),function(t){t.el.terminal.destroy()}),o.terminalViews=u,e.nodeView.render(),1==t.data_outputs.length&&"collection_type"in t.data_outputs[0]&&o.updateDataOutput(t.data_outputs[0]),r.replaceWith(a),"workflow_outputs"in t&&(this.workflow_outputs=workflow_outputs||[]),this.markChanged(),this.redraw()},error:function(t){var e=$(this.element).find(".toolFormBody");e.find("div").remove();var o="
"+t+"
";this.config_form=o,e.html(o),this.app.workflow.node_changed(this)},markChanged:function(){this.app.workflow.node_changed(this)}});t.default=n}); +define("mvc/workflow/workflow-node",["exports","mvc/workflow/workflow-view-node"],function(t,e){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=function(t){return t&&t.__esModule?t:{default:t}}(e),n=Backbone.Model.extend({initialize:function(t,e){this.app=t,this.element=e.element,this.input_terminals={},this.output_terminals={},this.errors={},this.workflow_outputs=[]},getWorkflowOutput:function(t){return _.findWhere(this.workflow_outputs,{output_name:t})},isWorkflowOutput:function(t){return void 0!==this.getWorkflowOutput(t)},removeWorkflowOutput:function(t){for(;this.isWorkflowOutput(t);)this.workflow_outputs.splice(this.getWorkflowOutput(t),1)},addWorkflowOutput:function(t,e){if(!this.isWorkflowOutput(t)){var o={output_name:t};return e&&(o.label=e),this.workflow_outputs.push(o),!0}return!1},labelWorkflowOutput:function(t,e){var o=!1,n=null;if(this.isWorkflowOutput(t)){var i=this.getWorkflowOutput(t);n=i.label,i.label=e,o=n!=e}else o=this.addWorkflowOutput(t,e);return o&&(this.app.workflow.updateOutputLabel(n,e),this.markChanged(),this.nodeView.redrawWorkflowOutputs()),o},connectedOutputTerminals:function(){return this._connectedTerminals(this.output_terminals)},_connectedTerminals:function(t){var e=[];return $.each(t,function(t,o){o.connectors.length>0&&e.push(o)}),e},hasConnectedOutputTerminals:function(){var t=this.output_terminals;for(var e in t)if(t[e].connectors.length>0)return!0;return!1},connectedMappedInputTerminals:function(){return this._connectedMappedTerminals(this.input_terminals)},hasConnectedMappedInputTerminals:function(){var t=this.input_terminals;for(var e in t){var o=t[e];if(o.connectors.length>0&&o.isMappedOver())return!0}return!1},_connectedMappedTerminals:function(t){var e=[];return $.each(t,function(t,o){o.mapOver().isCollection&&o.connectors.length>0&&e.push(o)}),e},mappedInputTerminals:function(){return this._mappedTerminals(this.input_terminals)},_mappedTerminals:function(t){var e=[];return $.each(t,function(t,o){o.mapOver().isCollection&&e.push(o)}),e},hasMappedOverInputTerminals:function(){var t=!1;return _.each(this.input_terminals,function(e){e.mapOver().isCollection&&(t=!0)}),t},redraw:function(){$.each(this.input_terminals,function(t,e){e.redraw()}),$.each(this.output_terminals,function(t,e){e.redraw()})},destroy:function(){$.each(this.input_terminals,function(t,e){e.destroy()}),$.each(this.output_terminals,function(t,e){e.destroy()}),this.app.workflow.remove_node(this),$(this.element).remove()},make_active:function(){$(this.element).addClass("toolForm-active")},make_inactive:function(){var t=this.element.get(0);!function(e){e.removeChild(t),e.appendChild(t)}(t.parentNode),$(t).removeClass("toolForm-active")},init_field_data:function(t){t.type&&(this.type=t.type),this.name=t.name,this.config_form=t.config_form,this.tool_version=this.config_form&&this.config_form.version,this.tool_state=t.tool_state,this.errors=t.errors,this.tooltip=t.tooltip?t.tooltip:"",this.annotation=t.annotation,this.post_job_actions=t.post_job_actions?t.post_job_actions:{},this.label=t.label,this.uuid=t.uuid,this.workflow_outputs=t.workflow_outputs?t.workflow_outputs:[];var e=this,n=new o.default({el:this.element[0],node:e});e.nodeView=n,$.each(t.data_inputs,function(t,e){n.addDataInput(e)}),t.data_inputs.length>0&&t.data_outputs.length>0&&n.addRule(),$.each(t.data_outputs,function(t,e){n.addDataOutput(e)}),n.render(),this.app.workflow.node_changed(this,!0)},update_field_data:function(t){var e=this,o=e.nodeView,n=[];if($.each(o.outputViews,function(e,o){var i=o.output.name,r=t.data_outputs,u=!1;_.each(r,function(t){t.name==i&&(u=!0)}),!1===u&&n.push(i)}),_.each(n,function(t){_.each(o.outputViews[t].terminalElement.terminal.connectors,function(t){t&&t.destroy()}),o.outputViews[t].remove(),delete o.outputViews[t],delete e.output_terminals[t]}),$.each(e.workflow_outputs,function(t,o){o&&!e.output_terminals[o.output_name]&&e.workflow_outputs.splice(t,1)}),$.each(t.data_outputs,function(t,n){o.outputViews[n.name]?(e.output_terminals[n.name].datatypes=n.extensions,e.output_terminals[n.name].destroyInvalidConnections()):o.addDataOutput(n)}),this.tool_state=t.tool_state,this.config_form=t.config_form,this.tool_version=this.config_form&&this.config_form.version,this.errors=t.errors,this.annotation=t.annotation,this.label=t.label,"post_job_actions"in t){var i=t.post_job_actions;this.post_job_actions=i||{}}e.nodeView.renderToolErrors();var r=o.$("div.inputs"),u=o.newInputsDiv(),a={};_.each(t.data_inputs,function(t){var o=e.nodeView.addDataInput(t,u);a[t.name]=o}),_.each(_.difference(_.values(o.terminalViews),_.values(a)),function(t){t.el.terminal.destroy()}),o.terminalViews=a,e.nodeView.render(),1==t.data_outputs.length&&"collection_type"in t.data_outputs[0]&&o.updateDataOutput(t.data_outputs[0]),r.replaceWith(u),"workflow_outputs"in t&&(this.workflow_outputs=t.workflow_outputs?t.workflow_outputs:[]),this.markChanged(),this.redraw()},error:function(t){var e=$(this.element).find(".toolFormBody");e.find("div").remove();var o="
"+t+"
";this.config_form=o,e.html(o),this.app.workflow.node_changed(this)},markChanged:function(){this.app.workflow.node_changed(this)}});t.default=n}); //# sourceMappingURL=../../../maps/mvc/workflow/workflow-node.js.map diff --git a/test/api/test_configuration.py b/test/api/test_configuration.py index c6927a3d8d46..48ba5310a2ce 100644 --- a/test/api/test_configuration.py +++ b/test/api/test_configuration.py @@ -3,6 +3,9 @@ assert_has_keys, assert_not_has_keys, ) +from base.populators import ( + LibraryPopulator +) TEST_KEYS_FOR_ALL_USERS = [ 'enable_unique_workflow_defaults', @@ -24,6 +27,10 @@ class ConfigurationApiTestCase(api.ApiTestCase): + def setUp(self): + super(ConfigurationApiTestCase, self).setUp() + self.library_populator = LibraryPopulator(self) + def test_normal_user_configuration(self): config = self._get_configuration() assert_has_keys(config, *TEST_KEYS_FOR_ALL_USERS) @@ -34,6 +41,22 @@ def test_admin_user_configuration(self): assert_has_keys(config, *TEST_KEYS_FOR_ALL_USERS) assert_has_keys(config, *TEST_KEYS_FOR_ADMIN_ONLY) + def test_admin_decode_id(self): + new_lib = self.library_populator.new_library('DecodeTestLibrary') + decode_response = self._get("configuration/decode/" + new_lib["id"], admin=True) + response_id = decode_response.json()["decoded_id"] + decoded_library_id = self.security.decode_id(new_lib["id"]) + assert decoded_library_id == response_id + # fake valid folder id by prepending F + valid_encoded_folder_id = 'F' + new_lib["id"] + folder_decode_response = self._get("configuration/decode/" + valid_encoded_folder_id, admin=True) + folder_response_id = folder_decode_response.json()["decoded_id"] + assert decoded_library_id == folder_response_id + + def test_normal_user_decode_id(self): + decode_response = self._get("configuration/decode/badhombre", admin=False) + self._assert_status_code_is(decode_response, 403) + def _get_configuration(self, data={}, admin=False): response = self._get("configuration", data=data, admin=admin) self._assert_status_code_is(response, 200) diff --git a/test/api/test_history_contents.py b/test/api/test_history_contents.py index bc2d59824a43..5cb2822556bd 100644 --- a/test/api/test_history_contents.py +++ b/test/api/test_history_contents.py @@ -221,7 +221,42 @@ def test_hdca_copy(self): assert len(self._get("histories/%s/contents/dataset_collections" % second_history_id).json()) == 0 create_response = self._post("histories/%s/contents/dataset_collections" % second_history_id, create_data) self.__check_create_collection_response(create_response) - assert len(self._get("histories/%s/contents/dataset_collections" % second_history_id).json()) == 1 + contents = self._get("histories/%s/contents/dataset_collections" % second_history_id).json() + assert len(contents) == 1 + new_forward, _ = self.__get_paired_response_elements(contents[0]) + self._assert_has_keys(new_forward, "history_id") + assert new_forward["history_id"] == self.history_id + + def test_hdca_copy_and_elements(self): + hdca = self.dataset_collection_populator.create_pair_in_history(self.history_id).json() + hdca_id = hdca["id"] + second_history_id = self._new_history() + create_data = dict( + source='hdca', + content=hdca_id, + copy_elements=True, + ) + assert len(self._get("histories/%s/contents/dataset_collections" % second_history_id).json()) == 0 + create_response = self._post("histories/%s/contents/dataset_collections" % second_history_id, create_data) + self.__check_create_collection_response(create_response) + + contents = self._get("histories/%s/contents/dataset_collections" % second_history_id).json() + assert len(contents) == 1 + new_forward, _ = self.__get_paired_response_elements(contents[0]) + self._assert_has_keys(new_forward, "history_id") + assert new_forward["history_id"] == second_history_id + + def __get_paired_response_elements(self, contents): + hdca = self.__show(contents).json() + self._assert_has_keys(hdca, "name", "deleted", "visible", "elements") + elements = hdca["elements"] + assert len(elements) == 2 + element0 = elements[0] + element1 = elements[1] + self._assert_has_keys(element0, "object") + self._assert_has_keys(element1, "object") + + return element0["object"], element1["object"] def test_hdca_from_library_datasets(self): ld = self.library_populator.new_library_dataset("el1") diff --git a/tools/stats/gsummary.py b/tools/stats/gsummary.py index 44ea737d6722..276a30f93493 100755 --- a/tools/stats/gsummary.py +++ b/tools/stats/gsummary.py @@ -59,7 +59,7 @@ def main(): except Exception: pass - tmp_file = tempfile.NamedTemporaryFile('w+b') + tmp_file = tempfile.NamedTemporaryFile('w+') # Write the R header row to the temporary file hdr_str = "\t".join("c%s" % str(col + 1) for col in cols) tmp_file.write("%s\n" % hdr_str)