ESP Dev ‐ Javascript - GTAC-MGI/GTAC-ESP-LIMS GitHub Wiki

Javascript Development

invokable.js - use to add functions for onRender() and onChange() event handlers. prefer this to inline. Loaded in LIMS, Reports, and Applet apps. Therefore, any functions, objects, or variables placed in this file are available to protocol event handlers (onrender, onchange) as well as to reports and applets. Other than loading symbols from this file, ESP does not do anything special with this file.

Reports are very similar to Applets, just in a different part of the UI (intent is read-only reports vs user-action driven applets). Both have access to base.css and general-reports.css. base.css has utility classes! See curation_utility.html for reference.


After updating invokables.js, you need to run:

make clientext

and do a hard refresh in your browser.


Passing worksheet values to JS

Use hidden fields populated with default values using the LIMS expression API to pass values along to onChange / onRender js functions. use something like:

{{ chain_info() }}

See: https://l7informatics.zendesk.com/hc/en-us/requests/1367


REST API

  • use fetch() for more control over hitting up the API rather than L7's JS functions

  • it's best to use /api/workflow_intance/uuid as it has both worksheet (step instances) and resource val (sample) data - rather than querying each sample individually (though you still need to get the workflow instance uuid from api/sample_sheets/${api.sampleSheetUuid})

  • query for multiple samples and sheets:

    • /api/samples?name=ESP000001
    • /api/samples?names=["ESP000001","ESP000002"]
    • /api/samples?uuids=["uuid1","uuid2","uuid3"]
    • /api/samples?name.like="ESP00"
    • /api/samples?names=["LIB00001", "LIB00002"]/children
    • /api/samples/82263d1a-3f5f-4ee9-849d-3ea7df69cb42/parents
    • /api/sample_sheets?name="Blood Banking 1"
    • /api/sample_sheets?name.like="Blood"
    • /api/sample_sheets?name.like="Blood"&params=["uuid"] returns only UUID
    • /api/sample_sheets?name.like="Blood"&ingore_deleted=true
    • /api/sample_sheets?tag="manual"
    • /api/samples?owner=Matthew Cordes
    • api/workflow_instances?uuids=["228b5f225b-cc6f-40de-9972-cdf722d34c2a","22deecf9d8-305d-445d-9469-3ee031e31b4b"]
    • api/projects/<project uuid>/samples
    • api/workflow_instances?name="092923_CLE_Illumina Sequencing"
    • api/workflow_instance_samples everything in the LIMS queue
  • query no more than ~150 batches at a time!

const options = {
  method: 'GET',
  headers: {
    'Content-Type': 'application/json',
    Accept: 'application/json',
    Authorization: 'Bearer API_KEY_HERE'
  },
  body: 'false'
};

fetch('https://gtac-mgi-lims.wustl.edu/api/samples/1314592b-d6b7-4936-ac45-ef4ab2795f80', options)
  .then(response => response.json())
  .then(response => console.log(response))
  .catch(err => console.error(err));  

Updating a Sample via PUT Request

function onchange_complete_update_rv(api, row, tgt_col, tgt_rv) {
	let uuid = api.getSampleUuidAt(row);
	let sheet_val = api.getDataAt(row, tgt_col) || null;
	let payload = { "resource_vals": [{"name": tgt_rv, "value": sheet_val}] };
	api.putToESP(
		`/api/samples/${uuid}`,
		JSON.stringify(payload),
		data => {},
		err => {
			console.error(err);
			api.showNotification(`Could not update ${tgt_rv}.`, "error");
		}
	);
}

Updating an Applet

esp import applet '/opt/l7esp/data/project/content/applets/applets.yml'


Invokables Misc

invokables.js has access to:

  • flatpicker (for date manipulation)
  • tippy.js

interesting api methods not documented:

  • getSelectedSamples()
  • getSelectedCells()
  • setEmailNotification()
  • getProtocolName()
  • getWorkflowName()
  • checkRequiredFields()

Toast examples:

appsApi.$toast({title: 'Error', description:'An error occured!', status: 'error'})

appsApi.$toast({title: 'Success', description: 'Successful execution!', status: 'success'})


Customizing protocols with JS

  • you can use api.runPipeline() to run a pipeline script without having a button and have the user run it manually