diff --git a/api/config_sample.php b/api/config_sample.php index 97d9fc85d..9be9cf64f 100644 --- a/api/config_sample.php +++ b/api/config_sample.php @@ -406,6 +406,34 @@ $dials_rest_jwt = ""; $dials_rest_url_rings = false; + # Upstream reprocessing pipelines, by beamline type + $upstream_reprocessing_pipelines = array( + 'sm' => array( + array('NAME' => 'Xia2 DIALS', 'VALUE' => 'xia2-dials'), + array('NAME' => 'Xia2 DIALS aimless', 'VALUE' => 'xia2-dials-aimless'), + ), + 'default' => array( + array('NAME' => 'Xia2 DIALS', 'VALUE' => 'xia2-dials'), + array('NAME' => 'Xia2 3dii', 'VALUE' => 'xia2-3dii'), + array('NAME' => 'Fast DP', 'VALUE' => 'fast_dp'), + array('NAME' => 'autoPROC', 'VALUE' => 'autoPROC'), + ), + ); + + # Downstream reprocessing pipelines, by beamline type + $downstream_reprocessing_pipelines = array( + 'sm' => array( + array('NAME' => 'shelxt', 'VALUE' => 'trigger-shelxt'), + ), + 'default' => array( + array('NAME' => 'Dimple', 'VALUE' => 'trigger-dimple'), + array('NAME' => 'Fast EP', 'VALUE' => 'trigger-fastep'), + array('NAME' => 'Big EP', 'VALUE' => 'trigger-bigep'), + array('NAME' => 'MrBUMP', 'VALUE' => 'trigger-mrbump'), + ), + ); + + # Add a button to upload file to CCP4 cloud #$ccp4_cloud_upload_url = 'https://data.cloud.ccp4.ac.uk/api/data/<%=USERNAME%>/<%=FACILITYNAME%>/<%=IMAGEPREFIX%>_<%=DATACOLLECTIONNUMBER%>/upload'; ?> diff --git a/api/index.php b/api/index.php index 60d180f74..a16c214de 100644 --- a/api/index.php +++ b/api/index.php @@ -73,8 +73,8 @@ function setupApplication($mode): Slim $valid_components, $enabled_container_types, $synchweb_version, $redirects, $shipping_service_app_url, $use_shipping_service_redirect, $use_shipping_service_redirect_incoming_shipments, $dials_rest_url_rings, $closed_proposal_link, $ccp4_cloud_upload_url, - $only_staff_can_assign, $industrial_prop_codes, $prop_codes_data_deleted, $container_types_with_parents, - $bl_capacity; + $only_staff_can_assign, $industrial_prop_codes, $upstream_reprocessing_pipelines, $downstream_reprocessing_pipelines, + $prop_codes_data_deleted, $container_types_with_parents, $bl_capacity; $app->contentType('application/json'); $options = $app->container['options']; $app->response()->body(json_encode(array( @@ -97,16 +97,18 @@ function setupApplication($mode): Slim 'valid_components' => $valid_components, 'enabled_container_types' => $enabled_container_types, 'synchweb_version' => $synchweb_version, + 'redirects' => $redirects, 'shipping_service_app_url' => $use_shipping_service_redirect || $use_shipping_service_redirect_incoming_shipments ? $shipping_service_app_url : null, 'shipping_service_app_url_incoming' => $use_shipping_service_redirect_incoming_shipments ? $shipping_service_app_url : null, - 'closed_proposal_link' => $closed_proposal_link, 'dials_rest_url_rings' => $dials_rest_url_rings, + 'closed_proposal_link' => $closed_proposal_link, 'ccp4_cloud_upload_url' => $ccp4_cloud_upload_url, - 'redirects' => $redirects, 'only_staff_can_assign' => $only_staff_can_assign, - 'container_types_with_parents' => $container_types_with_parents, 'industrial_prop_codes' => $industrial_prop_codes, + 'upstream_reprocessing_pipelines' => $upstream_reprocessing_pipelines, + 'downstream_reprocessing_pipelines' => $downstream_reprocessing_pipelines, 'prop_codes_data_deleted' => $prop_codes_data_deleted ?? array(), + 'container_types_with_parents' => $container_types_with_parents, 'bl_capacity' => $bl_capacity, ))); }); diff --git a/api/src/Downstream/Type/FastEp.php b/api/src/Downstream/Type/FastEp.php index 30011c8d6..092c1d4b4 100644 --- a/api/src/Downstream/Type/FastEp.php +++ b/api/src/Downstream/Type/FastEp.php @@ -16,6 +16,15 @@ function results() { 'ATOMS' => array(array('sad_fa.pdb file not found')) ); + $integrator = $this->_lookup_autoproc( + null, + $this->process['PARAMETERS']['scaling_id'] + ); + if ($integrator) { + $dat['PARENTAUTOPROCPROGRAM'] = $integrator['PROCESSINGPROGRAMS']; + $dat['PARENTAUTOPROCPROGRAMID'] = $integrator['AUTOPROCPROGRAMID']; + } + $ats = array(); $pdb = $this->_get_attachments("sad_fa.pdb"); if ($pdb) { diff --git a/api/src/Downstream/Type/LigandFit.php b/api/src/Downstream/Type/LigandFit.php index 068cb48f4..fb165959c 100644 --- a/api/src/Downstream/Type/LigandFit.php +++ b/api/src/Downstream/Type/LigandFit.php @@ -42,12 +42,13 @@ function _get_model_appaid() { } function results() { + $json_data = "[]"; $json_filepath = $this->_get_ligandfit_results_json(); if (sizeof($json_filepath)) { - $json_path = $json_filepath[0]["FILEPATH"] . "/" . $json_filepath[0]["FILENAME"] ; - $json_data = file_get_contents($json_path); - } else { - $json_data = "[]"; + $json_path = $json_filepath[0]["FILEPATH"] . "/" . $json_filepath[0]["FILENAME"]; + if (file_exists($json_path)) { + $json_data = file_get_contents($json_path); + } } $dat = array(); $appaid = $this->_get_model_appaid(); diff --git a/api/src/Downstream/Type/Shelxt.php b/api/src/Downstream/Type/Shelxt.php index c9422e0a5..c8beb2d7d 100644 --- a/api/src/Downstream/Type/Shelxt.php +++ b/api/src/Downstream/Type/Shelxt.php @@ -42,12 +42,13 @@ function _get_pdb() { } function results() { + $json_data = "[]"; $json_filepath = $this->_get_shelxt_results_json(); if (sizeof($json_filepath)) { - $json_path = $json_filepath[0]["FILEPATH"] . "/shelxt_results.json" ; - $json_data = file_get_contents($json_path); - } else { - $json_data = "[]"; + $json_path = $json_filepath[0]["FILEPATH"] . "/shelxt_results.json"; + if (file_exists($json_path)) { + $json_data = file_get_contents($json_path); + } } $dat = array(); $dat['BLOBS'] = 1; diff --git a/api/src/Page/Fault.php b/api/src/Page/Fault.php index 1c7f58004..56d622999 100644 --- a/api/src/Page/Fault.php +++ b/api/src/Page/Fault.php @@ -308,19 +308,14 @@ function _update_fault() # Return a list of beamlines with ids function _get_beamlines() { - $row_tmp = $this->db->pq("SELECT distinct beamlinename as name FROM blsession WHERE beamlinename NOT LIKE 'i04 1' ORDER BY beamlinename"); + $row_tmp = $this->db->pq("SELECT distinct beamlinename as name FROM blsession WHERE beamlinename != '' ORDER BY beamlinename"); $rows = array(); foreach ($row_tmp as $r) { array_push($rows, array('NAME' => $r['NAME'])); } - // $rows = array(array('NAME' => 'i02'), array('NAME' => 'i03'), array('NAME' => 'i04'), array('NAME' => 'i04-1'), array('NAME' => 'i24')); - - $bls = array(); - foreach ($rows as $r) - $bls[$r['NAME']] = $r['NAME']; - $this->_output($this->has_arg('array') ? $bls : $rows); + $this->_output($rows); } # ------------------------------------------------------------------------ @@ -348,19 +343,18 @@ function _get_systems() $rows = $this->db->pq("SELECT s.systemid, s.name, s.description, string_agg(hs.beamlinename) as beamlines FROM bf_system s INNER JOIN bf_system_beamline hs ON s.systemid = hs.systemid " . $where . " GROUP BY s.systemid, s.name, s.description ORDER BY s.name", $args); - $sys = array(); - foreach ($rows as $s) - $sys[$s['SYSTEMID']] = $s['NAME']; - - $this->_output($this->has_arg('array') ? $sys : $rows); + $this->_output($rows); } # ------------------------------------------------------------------------ # Return a list of components for a system on a beamline function _get_components() { - if (!$this->has_arg('sid')) - $this->_error('No systemid specified'); + if (!$this->has_arg('sid')) { + $this->_output(array()); + return; + } + $args = array($this->arg('sid')); if ($this->has_arg('bl')) @@ -381,19 +375,18 @@ function _get_components() $rows = $this->db->pq('SELECT c.componentid, c.name, c.description, string_agg(hc.beamlinename) as beamlines FROM bf_component c INNER JOIN bf_component_beamline hc ON c.componentid = hc.componentid WHERE c.systemid=:1' . $where . ' GROUP BY c.componentid, c.name, c.description ORDER BY beamlines,c.name', $args); - $com = array(); - foreach ($rows as $c) - $com[$c['COMPONENTID']] = $c['NAME']; - - $this->_output($this->has_arg('array') ? $com : $rows); + $this->_output($rows); } # ------------------------------------------------------------------------ # Return a list of subcomponents for a component on a beamline function _get_subcomponents() { - if (!$this->has_arg('cid')) - $this->_error('No componentid specified'); + if (!$this->has_arg('cid')) { + $this->_output(array()); + return; + } + $args = array($this->arg('cid')); if ($this->has_arg('bl')) @@ -414,11 +407,7 @@ function _get_subcomponents() $rows = $this->db->pq('SELECT s.subcomponentid, s.name, s.description, string_agg(hs.beamlinename) as beamlines FROM bf_subcomponent s INNER JOIN bf_subcomponent_beamline hs ON s.subcomponentid = hs.subcomponentid WHERE s.componentid=:1' . $where . ' GROUP BY s.subcomponentid, s.name, s.description ORDER BY s.name', $args); - $scom = array(); - foreach ($rows as $s) - $scom[$s['SUBCOMPONENTID']] = $s['NAME']; - - $this->_output($this->has_arg('array') ? $scom : $rows); + $this->_output($rows); } diff --git a/api/src/Page/Sample.php b/api/src/Page/Sample.php index 24b57298d..69b58bfbe 100644 --- a/api/src/Page/Sample.php +++ b/api/src/Page/Sample.php @@ -17,8 +17,8 @@ class Sample extends Page 's' => '\w+', 'prop' => '\w+\d+', 'term' => '\w+', - 'pid' => '\d+', - 'sid' => '\d+', + 'pid' => '-?\d+', + 'sid' => '-?\d+', 'ssid' => '\d+', 'cid' => '\d+', 'crid' => '\d+', diff --git a/client/src/js/modules/dc/views/autointegration.js b/client/src/js/modules/dc/views/autointegration.js index 9f35870a6..3288e26ae 100644 --- a/client/src/js/modules/dc/views/autointegration.js +++ b/client/src/js/modules/dc/views/autointegration.js @@ -184,6 +184,11 @@ define(['marionette', } this.$el.slideDown() + + if (typeof this.getOption('onReady') === 'function') { + this.getOption('onReady')(this) + } + } }) diff --git a/client/src/js/modules/dc/views/dc.js b/client/src/js/modules/dc/views/dc.js index 0d186b6ce..9227e3600 100644 --- a/client/src/js/modules/dc/views/dc.js +++ b/client/src/js/modules/dc/views/dc.js @@ -167,15 +167,20 @@ define(['marionette', } else this.strat.$el.slideToggle() }, - loadAP: function(e) { + loadAP: function(e, callback) { if (!this.ap) { this.ap = new DCAutoIntegrationView({ - id: this.model.get('ID'), - dcPurgedProcessedData: this.model.get('PURGEDPROCESSEDDATA'), - el: this.$el.find('div.autoproc'), - parent: this.model - }) - } else this.ap.$el.slideToggle() + id: this.model.get('ID'), + dcPurgedProcessedData: this.model.get('PURGEDPROCESSEDDATA'), + el: this.$el.find('div.autoproc'), + parent: this.model, + onReady: callback + }) + } else { + this.ap.$el.slideToggle(() => { + if (callback) callback(this.ap); + }); + } }, @@ -185,7 +190,8 @@ define(['marionette', id: this.model.get('ID'), dcPurgedProcessedData: this.model.get('PURGEDPROCESSEDDATA'), el: this.$el.find('div.downstream'), - holderWidth: this.$el.find('.holder').width() + holderWidth: this.$el.find('.holder').width(), + upstreamLink: true, }) } else this.dp.$el.slideToggle() }, diff --git a/client/src/js/modules/dc/views/downstream.js b/client/src/js/modules/dc/views/downstream.js index b4eeb5f6d..4da0da300 100644 --- a/client/src/js/modules/dc/views/downstream.js +++ b/client/src/js/modules/dc/views/downstream.js @@ -9,18 +9,17 @@ define(['backbone', 'marionette', 'modules/dc/views/bigep', 'modules/dc/views/shelxt', 'modules/dc/views/ligandfit', - 'templates/dc/downstreamerror.html' ], function(Backbone, Marionette, TabView, DownStreams, DownstreamWrapper, TableView, - FastEP, DIMPLE, MrBUMP, BigEP, Shelxt, LigandFit, downstreamerror) { + FastEP, DIMPLE, MrBUMP, BigEP, Shelxt, LigandFit) { var dcPurgedProcessedData = "0"; // dataCollection.PURGEDPROCESSEDDATA via options from DC.js var DownstreamsCollection = Backbone.Collection.extend() var DownStreamError = Marionette.ItemView.extend({ - template: downstreamerror + template: _.template('

This processing job failed: <%-PROCESS.PROCESSINGMESSAGE%>

') }) var DownStreamRunning = Marionette.ItemView.extend({ @@ -69,12 +68,17 @@ define(['backbone', 'marionette', 'LigandFit': LigandFit, } - if (model.get('PROCESS').PROCESSINGSTATUS != 1) { + if (model.get('PROCESS').PROCESSINGSTATUS == null) { return DownstreamWrapper.extend({ links: false, dcPurgedProcessedData, - childView: model.get('PROCESS').PROCESSINGSTATUS == null - ? DownStreamRunning : DownStreamError + childView: DownStreamRunning + }) + } else if (model.get('PROCESS').PROCESSINGSTATUS != 1) { + return DownstreamWrapper.extend({ + mapLink: false, + dcPurgedProcessedData, + childView: DownStreamError }) } @@ -106,6 +110,7 @@ define(['backbone', 'marionette', } }, DCID: this.getOption('DCID'), + upstreamLink: this.getOption('upstreamLink'), } }, @@ -128,6 +133,7 @@ define(['backbone', 'marionette', downstreams: this.getOption('downstreams'), DCID: this.getOption('id'), mapButton: this.getOption('mapButton'), + upstreamLink: this.getOption('upstreamLink'), } }, @@ -175,7 +181,8 @@ define(['backbone', 'marionette', downstreams: this.collection, id: this.getOption('id'), el: this.$el.find('.res'), - holderWidth: this.$el.parent().width() + holderWidth: this.$el.parent().width(), + upstreamLink: this.getOption('upstreamLink'), })) } else { this.$el.addClass('ui-tabs') diff --git a/client/src/js/modules/dc/views/downstreamreprocess.js b/client/src/js/modules/dc/views/downstreamreprocess.js index 4154a2c68..1ea5f86d7 100644 --- a/client/src/js/modules/dc/views/downstreamreprocess.js +++ b/client/src/js/modules/dc/views/downstreamreprocess.js @@ -100,6 +100,10 @@ define(['backbone', 'marionette', 'views/dialog', this.model.set('PIPELINENAME', this.ui.pipeline.find('option:selected').text()) var btns = this.buttons var warning = '' + if (!this.model.get('PIPELINENAME')) { + warning = ' No pipelines available' + btns = this.disabledButtons + } if (['MrBUMP', 'Dimple'].includes(this.model.get('PIPELINENAME')) && this.type.includes('autoPROC')) { warning = ' Cannot rerun ' + this.model.get('PIPELINENAME') + ' on ' + this.type + ' results' btns = this.disabledButtons @@ -112,7 +116,7 @@ define(['backbone', 'marionette', 'views/dialog', warning = ' Cannot run Dimple as no PDBs defined' btns = this.disabledButtons } - if (this.model.get('PIPELINENAME') === 'MrBUMP' && this.model.get('HASSEQ') === 'No') { + if (this.model.get('PIPELINENAME') === 'MrBUMP' && (this.model.get('HASSEQ') === 'No' || !this.model.get('HASSEQ'))) { warning = ' Cannot run MrBUMP as no sequence defined' btns = this.disabledButtons } @@ -120,7 +124,7 @@ define(['backbone', 'marionette', 'views/dialog', warning = ' Cannot run Fast EP as no anomalous scatterer defined' btns = this.disabledButtons } - if (this.model.get('PIPELINENAME') === 'Big EP' && this.model.get('HASSEQ') === 'No') { + if (this.model.get('PIPELINENAME') === 'Big EP' && (this.model.get('HASSEQ') === 'No' || !this.model.get('HASSEQ'))) { warning = ' Cannot run Big EP as no sequence defined' btns = this.disabledButtons } @@ -155,7 +159,7 @@ define(['backbone', 'marionette', 'views/dialog', initialize: function(options) { - this.proteins = new Proteins(null, { queryParams: { sid: options.model.get('BLSAMPLEID') } }) + this.proteins = new Proteins(null, { queryParams: { sid: options.model.get('BLSAMPLEID') || -1 } }) this._ready = this.proteins.fetch() this._ready.done(this.doOnReady.bind(this)) this.scalingid = options.scalingid @@ -169,24 +173,23 @@ define(['backbone', 'marionette', 'views/dialog', }, onRender: function() { - - this.pipelines = new Pipelines([ - { NAME: 'Dimple', VALUE: 'trigger-dimple' }, - { NAME: 'Fast EP', VALUE: 'trigger-fastep' }, - { NAME: 'Big EP', VALUE: 'trigger-bigep' }, - { NAME: 'MrBUMP', VALUE: 'trigger-mrbump' }, - ]) - - this.ui.pipeline.html(this.pipelines.opts()) + const dspls = app.options.get('downstream_reprocessing_pipelines') + if (dspls) { + const pls = dspls[app.type] ?? dspls['default']; + this.pipelines = new Pipelines(pls) + this.ui.pipeline.html(this.pipelines.opts()) + } }, - + doOnReady: function() { var protein = this.proteins.at(0) - var self = this - _.each(['ACRONYM','PROTEINID','HASSEQ','PDBS','ANOMALOUSSCATTERER'], function(k) { - self.model.set(k, protein.get(k)) - }) - this.pdbs = new PDBs(null, { pid: this.model.get('PROTEINID') }) + if (protein) { + var self = this + _.each(['ACRONYM','PROTEINID','HASSEQ','PDBS','ANOMALOUSSCATTERER'], function(k) { + self.model.set(k, protein.get(k)) + }) + } + this.pdbs = new PDBs(null, { pid: this.model.get('PROTEINID') || -1 }) this.pdbs.fetch().done(this.updatePipeline.bind(this)) this.collection = new IDDataCollections() if (this.model) { diff --git a/client/src/js/modules/dc/views/downstreamwrapper.js b/client/src/js/modules/dc/views/downstreamwrapper.js index 23b5462cb..d435a6e43 100644 --- a/client/src/js/modules/dc/views/downstreamwrapper.js +++ b/client/src/js/modules/dc/views/downstreamwrapper.js @@ -29,6 +29,30 @@ define(['backbone', 'marionette', 'click .logf': 'showLog', 'click a.pattach': 'showAttachments', 'click .dll': utils.signHandler, + 'click a.viewupstream': 'viewUpstream', + }, + + viewUpstream: function(e) { + e.preventDefault() + + const pappid = this.model.get('PARENTAUTOPROCPROGRAMID') + const downstream = this.$el.closest('.downstream') + const ap = downstream.siblings('.ap') + const autoproc = downstream.siblings('.autoproc') + + const clickTab = (apView) => { + let tab = autoproc.find('a[href="#tabs-' + pappid + '"]') + if (tab.length) { + tab.trigger('click') + $('html, body').animate({ scrollTop: tab.offset().top }) + } + } + + if (autoproc.is(':visible')) { + clickTab(this.ap) + } else { + ap.trigger('click', clickTab) + } }, showAttachments: function(e) { @@ -82,6 +106,10 @@ define(['backbone', 'marionette', links = links.slice(1) } + if (this.getOption('upstreamLink')) { + links.push(' View Upstream') + } + this.ui.links.append(links.join(' ')) mapButton = this.ui.links.find('a.view') } diff --git a/client/src/js/modules/dc/views/reprocess2.js b/client/src/js/modules/dc/views/reprocess2.js index 5ebd0f8dd..6ee085e9a 100644 --- a/client/src/js/modules/dc/views/reprocess2.js +++ b/client/src/js/modules/dc/views/reprocess2.js @@ -102,7 +102,7 @@ define(['backbone', 'marionette', 'views/dialog', selectAll: function(e) { - e.preventDefault() + if (e) e.preventDefault() var si = parseInt(this.model.get('SI')) var ni = parseInt(this.model.get('NUMIMG')) @@ -148,6 +148,20 @@ define(['backbone', 'marionette', 'views/dialog', this.$el.find('div input[type="text"]').css('width', '50px') this.ui.pipeline.html(this.getOption('pipelines').opts()) this.model.set('PIPELINE', this.ui.pipeline.val()) + + // check .distl element has been created before selecting all + const callback = (mutationList, observer) => { + for (const mutation of mutationList) { + for (const node of mutation.addedNodes) { + if (node.nodeType === Node.ELEMENT_NODE && node.querySelector('.distl')) { + this.selectAll() + observer.disconnect() + } + } + } + } + const observer = new MutationObserver(callback) + observer.observe(document.getElementById("dialog"), { childList: true, subtree: true }) }, toggleSG: function(e) { @@ -247,6 +261,12 @@ define(['backbone', 'marionette', 'views/dialog', sm: 'input[name=sm]', indexingMethod: 'select[name=method]', absorptionLevel: 'select[name=absorption_level]', + a: 'input[name=a]', + b: 'input[name=b]', + c: 'input[name=c]', + al: 'input[name=alpha]', + be: 'input[name=beta]', + ga: 'input[name=gamma]', }, buttons: { @@ -259,6 +279,7 @@ define(['backbone', 'marionette', 'views/dialog', 'click a.opt': 'toggleOpts', 'click @ui.ind': 'toggleIndividual', 'change @ui.pipeline': 'updatePipeline', + 'change @ui.indexingMethod': 'updateIndexingMethod', 'click a.multicrystal': 'closeDialog', }, @@ -276,11 +297,40 @@ define(['backbone', 'marionette', 'views/dialog', } }, + updateIndexingMethod: function() { + if (this.ui.indexingMethod.val() == 'real_space_grid_search') { + const st = this.ui.ind.is(':checked') + if (st) { + let eachHasCell = true + this.distlview.children.each(function(v) { + if (!v.ui.a.val() || !v.ui.b.val() || !v.ui.c.val() || + !v.ui.al.val() || !v.ui.be.val() || !v.ui.ga.val()) { + v.ui.cell.show() + eachHasCell = false + } + }) + if (!eachHasCell) { + app.alert({ message: 'Real Space Grid Search requires unit cell to be populated' }) + this.ui.indexingMethod.val('') + } + } else { + if (!this.ui.a.val() || !this.ui.b.val() || !this.ui.c.val() || + !this.ui.al.val() || !this.ui.be.val() || !this.ui.ga.val()) { + app.alert({ message: 'Real Space Grid Search requires unit cell to be populated' }) + this.ui.indexingMethod.val('') + this.ui.cell.show() + } + } + } + }, + toggleIndividual: function(e) { - var st = this.ui.ind.is(':checked') + const st = this.ui.ind.is(':checked') st ? this.ui.mul.hide() : this.ui.mul.show() + if (st) this.ui.cell.hide() this.distlview.children.each(function(v) { v.setInd(st) + if (!st) v.ui.cell.hide() }) }, @@ -309,7 +359,7 @@ define(['backbone', 'marionette', 'views/dialog', var s = this.collection.where({ selected: true }) if (!s.length) { - app.alert({ message: 'Please selected some data sets to integrate' }) + app.alert({ message: 'Please select some data sets to integrate' }) return } @@ -530,18 +580,16 @@ define(['backbone', 'marionette', 'views/dialog', }, onRender: function() { - this.ui.opts.hide() + if (app.type != 'sm') this.ui.opts.hide() this.ui.cell.hide() - this.$el.find('span input[type="text"]').css('width', '50px') - - this.pipelines = new Pipelines([ - { NAME: 'Xia2 DIALS', VALUE: 'xia2-dials' }, - { NAME: 'Xia2 3dii', VALUE: 'xia2-3dii' }, - { NAME: 'Fast DP', VALUE: 'fast_dp' }, - { NAME: 'autoPROC', VALUE: 'autoPROC' }, - ]) + this.$el.find('span input[type="text"]').css('width', '55px') - this.ui.pipeline.html(this.pipelines.opts()) + const uspls = app.options.get('upstream_reprocessing_pipelines') + if (uspls) { + const pls = uspls[app.type] ?? uspls['default']; + this.pipelines = new Pipelines(pls) + this.ui.pipeline.html(this.pipelines.opts()) + } this.indexingMethods = new IndexingMethods([ { NAME: '-', VALUE: '' }, @@ -578,6 +626,7 @@ define(['backbone', 'marionette', 'views/dialog', var nm = model.clone() nm.set('CID', this.collection.length+1) this.collection.add(nm) + this.toggleIndividual() }, setCell: function(view, ap) { diff --git a/client/src/js/modules/fault/routes.js b/client/src/js/modules/fault/routes.js index ea591ca08..5b0eb5912 100644 --- a/client/src/js/modules/fault/routes.js +++ b/client/src/js/modules/fault/routes.js @@ -30,19 +30,20 @@ var bc = { title: 'Fault Database', url: '/fault' } const routes = [ { // sys, com and sub should all be ids of sub systems and components for the beamline - path: '/faults(/bl/)?:bl([a-zA-Z0-9_-]+)?(/sys/)?:sys([0-9]+)?(/com/)?:com([0-9]+)?(/sub/)?:sub([0-9]+)?(/page/)?:page([0-9]+)?', + path: '/faults(/bl/)?:bl([a-zA-Z0-9_-]+)?(/sys/)?:sys([0-9]+)?(/com/)?:com([0-9]+)?(/sub/)?:sub([0-9]+)?(/s/)?:s([a-zA-Z0-9_%-]+)?(/page/)?:page([0-9]+)?', name: 'faults-view', component: MarionetteView, props: route => ({ mview: FaultListView, options: { - collection: new Faults(null, { state: { currentPage: route.params.page ? parseInt(route.params.page) : 1} }) - }, - params: { - beamline: route.params.bl || '', - system: route.params.sys || '', - component: route.params.com || '', - subcomponent: route.params.sub || '' + collection: new Faults(null, { state: { currentPage: route.params.page ? parseInt(route.params.page) : 1} }), + params: { + beamline: route.params.bl || '', + system: route.params.sys || '', + component: route.params.com || '', + subcomponent: route.params.sub || '', + s: route.params.s, + }, }, breadcrumbs: [bc], }) diff --git a/client/src/js/modules/fault/views/filters.js b/client/src/js/modules/fault/views/filters.js index d58ef4d41..74d683c65 100644 --- a/client/src/js/modules/fault/views/filters.js +++ b/client/src/js/modules/fault/views/filters.js @@ -27,19 +27,28 @@ define(['marionette', }, updateUrlFragment: function() { - var frags = { + const frags = { bl: 'bl', sys: 'system', com: 'component', sub: 'subcomponent', } - var url = window.location.pathname + let url = window.location.pathname + + let searchFrag = '' + const searchMatch = url.match(/\/s\/.*$/) + if (searchMatch) { + searchFrag = searchMatch[0] + url = url.replace(searchFrag, '') + } + _.each(frags, function(v, f) { url = url.replace(new RegExp('\\/'+f+'\\/\\w+'), '') - if (this.ui[v].val() != 0) url += '/'+f+'/'+this.ui[v].val() + if (this.ui[v].val()) url += '/'+f+'/'+this.ui[v].val() }, this) + url += searchFrag window.history.pushState({}, '', url) }, @@ -50,6 +59,7 @@ define(['marionette', this.ui.system.val('') this.ui.component.val('') this.ui.subcomponent.val('') + this.updateUrlFragment() this.collection.fetch() this.updateSystems() @@ -61,13 +71,13 @@ define(['marionette', return self.ui.bl.val() } this.collection.queryParams.sid = function() { - if (self.ui.system.val() > 0) return self.ui.system.val() + return self.ui.system.val() } this.collection.queryParams.cid = function() { - if (self.ui.component.val() > 0) return self.ui.component.val() + return self.ui.component.val() } this.collection.queryParams.scid = function() { - if (self.ui.subcomponent.val() > 0) return self.ui.subcomponent.val() + return self.ui.subcomponent.val() } this.firstLoad = true @@ -85,12 +95,8 @@ define(['marionette', var self = this this.beamlines = new Beamlines() - this.beamlines.fetch().done(function() { - self.ui.bl.html(''+self.beamlines.opts()) - if (self.getOption('params')) self.ui.bl.val(self.getOption('params').beamline) - self.updateSystems() - }) - + this.updateBeamlines() + this.systems = new Systems(null, { queryParams: { bl: function() { @@ -123,35 +129,51 @@ define(['marionette', }) }, + updateBeamlines: function(e) { + this.beamlines.fetch().done(this.doUpdateBeamlines.bind(this,e)) + }, + doUpdateBeamlines: function(e) { + this.ui.bl.html(''+this.beamlines.opts()) + if (this.getOption('params') && this.getOption('params').beamline) { + this.ui.bl.val(this.getOption('params').beamline) + this.updateSystems() + } + }, updateSystems: function(e) { this.systems.fetch().done(this.doUpdateSystems.bind(this,e)) }, doUpdateSystems: function(e) { var val = this.ui.system.val() - this.ui.system.html(''+this.systems.opts()).val(val) - if (this.getOption('params') && this.firstLoad) this.ui.system.val(this.getOption('params').system) - if (e) this.collection.fetch() - this.updateComponents() + this.ui.system.html(''+this.systems.opts()).val(val) + if (this.getOption('params') && this.getOption('params').system && this.firstLoad) { + this.ui.system.val(this.getOption('params').system) + this.updateComponents() + } else { + this.collection.fetch() + } }, - updateComponents: function(e) { this.components.fetch().done(this.doUpdateComponents.bind(this,e)) }, doUpdateComponents: function(e) { var val = this.ui.component.val() - this.ui.component.html(''+this.components.opts()).val(val) - if (this.getOption('params') && this.firstLoad) this.ui.component.val(this.getOption('params').component) - this.updateSubComponents() - if (e) this.collection.fetch() + this.ui.component.html(''+this.components.opts()).val(val) + if (this.getOption('params') && this.getOption('params').component && this.firstLoad) { + this.ui.component.val(this.getOption('params').component) + this.updateSubComponents() + } else { + this.collection.fetch() + } }, + updateSubComponents: function(e) { this.subcomponents.fetch().done(this.doUpdateSubComponents.bind(this,e)) }, doUpdateSubComponents: function(e) { var val = this.ui.subcomponent.val() - this.ui.subcomponent.html(''+this.subcomponents.opts()).val(val) + this.ui.subcomponent.html(''+this.subcomponents.opts()).val(val) if (this.getOption('params') && this.firstLoad) this.ui.subcomponent.val(this.getOption('params').subcomponent) if (e || this.firstLoad) this.collection.fetch() if (this.firstLoad) this.firstLoad = false @@ -159,4 +181,4 @@ define(['marionette', }) -}) \ No newline at end of file +}) diff --git a/client/src/js/modules/fault/views/list.js b/client/src/js/modules/fault/views/list.js index a5125c878..313d5619a 100644 --- a/client/src/js/modules/fault/views/list.js +++ b/client/src/js/modules/fault/views/list.js @@ -33,7 +33,7 @@ define(['marionette', 'modules/fault/views/filters', 'views/table', 'utils/table }) } - this.table = new TableView({ collection: options.collection, columns: columns, tableClass: 'proposals', filter: this.getOption('search') ? 's' : false, loading: true, backgrid: { row: ClickableRow, emptyText: 'No faults found' } }) + this.table = new TableView({ collection: options.collection, columns: columns, tableClass: 'proposals', filter: 's', search: options.params.s, loading: true, backgrid: { row: ClickableRow, emptyText: 'No faults found' } }) if (this.getOption('filters')) this.filters = new FilterView({ collection: options.collection, params: this.getOption('params') }) }, @@ -48,4 +48,4 @@ define(['marionette', 'modules/fault/views/filters', 'views/table', 'utils/table }, }) -}) \ No newline at end of file +}) diff --git a/client/src/js/modules/types/mx/shipment/views/mx-container-view.vue b/client/src/js/modules/types/mx/shipment/views/mx-container-view.vue index 519838d9e..da6f4f9d9 100644 --- a/client/src/js/modules/types/mx/shipment/views/mx-container-view.vue +++ b/client/src/js/modules/types/mx/shipment/views/mx-container-view.vue @@ -66,7 +66,8 @@
  • Owner - Logs & Files - Download Zip -

    - -

    This processing job failed: <%-PROCESS.PROCESSINGMESSAGE%>

    diff --git a/client/src/js/templates/dc/reprocess.html b/client/src/js/templates/dc/reprocess.html index fdf575bb7..38f964cbf 100644 --- a/client/src/js/templates/dc/reprocess.html +++ b/client/src/js/templates/dc/reprocess.html @@ -11,8 +11,8 @@ | Pipeline : - High Res : Å - Low Res : Å | + High Res : Å + Low Res : Å | Space Group / Cell diff --git a/client/src/js/templates/dc/reprocess_dc.html b/client/src/js/templates/dc/reprocess_dc.html index f24b2cd57..35fc73955 100644 --- a/client/src/js/templates/dc/reprocess_dc.html +++ b/client/src/js/templates/dc/reprocess_dc.html @@ -7,8 +7,8 @@

    Pipeline - High Res Å - Low Res Å | + High Res Å + Low Res Å | Space Group / Cell
    diff --git a/client/src/js/templates/mc/datacollections.html b/client/src/js/templates/mc/datacollections.html index 7fa8058c3..9af214cb3 100644 --- a/client/src/js/templates/mc/datacollections.html +++ b/client/src/js/templates/mc/datacollections.html @@ -29,8 +29,8 @@

    Data Collections for <%-VISIT%>

    - - + + Integrate Xia2 Options