@@ -715,9 +927,13 @@ const createToast = (msg, levelClass="is-danger") => {
}
}
+/**
+ * Disables or enables a checkbox and its associated label.
+ * If the parent element is a .checkbox class, it will also be disabled or enabled.
+ * @param {HTMLElement} checkboxElt - The checkbox element.
+ * @param {boolean} state - The state to set for the checkbox and its label. True to disable, false to enable.
+ */
const disableCheckboxLabel = (checkboxElt, state) => {
- // if parent element is a .checkbox class, disable it too (uses Bulma CSS styling)
- // Meant for checkboxes where the label is also a clickable element
// NOTE: ".disable" attribute only applies to certain elements (https://www.w3schools.com/tags/att_disabled.asp)
if (checkboxElt.parentElement.classList.contains("checkbox")) {
if (state) {
@@ -728,7 +944,14 @@ const disableCheckboxLabel = (checkboxElt, state) => {
}
}
-// Create the template for the colorscale select2 option dropdown
+/**
+ * Formats the option text for a colorscale.
+ *
+ * @param {Object} option - The option object.
+ * @param {string} text - The text to be displayed.
+ * @param {boolean} [isContinuous=false] - Indicates if the colorscale is continuous.
+ * @returns {DocumentFragment} - The formatted option text.
+ */
const formatColorscaleOptionText = (option, text, isContinuous=false) => {
const fragment = document.createDocumentFragment();
@@ -753,8 +976,12 @@ const formatColorscaleOptionText = (option, text, isContinuous=false) => {
return fragment;
}
+/**
+ * Updates the gene select element with gene symbols.
+ * @param {string|null} analysisId - The analysis ID (optional).
+ * @returns {Promise
} - A promise that resolves when the gene select element is updated.
+ */
const geneSelectUpdate = async (analysisId=null) => {
- // Populate gene select element
try {
const geneSymbols = await curatorApiCallsMixin.fetchGeneSymbols(datasetId, analysisId);
updateGeneOptions(geneSymbols); // Come from curator specific code
@@ -763,8 +990,15 @@ const geneSelectUpdate = async (analysisId=null) => {
}
}
+/**
+ * Retrieves updates and additions to the plot from the plot_display_config JS object.
+ *
+ * @param {Object[]} plotConfObj - The plot configuration object.
+ * @param {string} plotType - The type of plot.
+ * @param {string} category - The category of updates to retrieve.
+ * @returns {Object} - The updates and additions to the plot.
+ */
const getPlotlyDisplayUpdates = (plotConfObj, plotType, category) => {
- // Get updates and additions to plot from the plot_display_config JS object
let updates = {};
for (const idx in plotConfObj) {
const conf = plotConfObj[idx];
@@ -777,7 +1011,12 @@ const getPlotlyDisplayUpdates = (plotConfObj, plotType, category) => {
return updates;
}
-/* Get HTML element value to save into plot config */
+/**
+ * Retrieves the value of a plot configuration element based on its class name.
+ *
+ * @param {string} className - The class name of the plot configuration element.
+ * @returns {boolean|string|undefined} - The value of the plot configuration element, or undefined if not found.
+ */
const getPlotConfigValueFromClassName = (className) => {
// NOTE: Some elements are only present in certain plot type configurations
@@ -793,7 +1032,10 @@ const getPlotConfigValueFromClassName = (className) => {
return undefined;
}
-/* Get order of series from sortable lists. Return object */
+/**
+ * Retrieves the plot order from the sortable container.
+ * @returns {Object} The plot order object.
+ */
const getPlotOrderFromSortable = () => {
const order = {};
for (const elt of document.getElementById("order_container").children) {
@@ -805,17 +1047,30 @@ const getPlotOrderFromSortable = () => {
return order;
}
+/**
+ * Retrieves the value from a select2 element.
+ * @param {HTMLSelectElement} select - The select2 element.
+ * @returns {string} - The value of the selected option.
+ */
const getSelect2Value = (select) => {
- // Get value from select2 element
return select.selectedOptions[0].data.value;
}
+/**
+ * Fetches the content of an HTML file from the specified URL.
+ *
+ * @param {string} url - The URL of the HTML file to fetch.
+ * @returns {Promise} - A promise that resolves with the content of the HTML file as a string.
+ */
const includeHtml = async (url) => {
const preResponse = await fetch(url, {cache: "reload"});
return await preResponse.text();
}
-/* Load custom plot options */
+/**
+ * Includes plot parameter options and performs necessary setup for plotting.
+ * @returns {Promise} A promise that resolves once the plot parameter options are included and setup is complete.
+ */
const includePlotParamOptions = async () => {
const plotType = getSelect2Value(plotTypeSelect);
@@ -850,7 +1105,12 @@ const includePlotParamOptions = async () => {
}
-// Load colorscale select2 object and populate with data
+/**
+ * Loads the colorscale select options based on the given plot type.
+ *
+ * @param {boolean} isContinuous - Indicates whether the plot type is continuous or discrete.
+ * @returns {void}
+ */
const loadColorscaleSelect = (isContinuous=false) => {
let filteredPalettes = availablePalettes;
@@ -885,7 +1145,12 @@ const loadColorscaleSelect = (isContinuous=false) => {
}
-/* Transform and load dataset data into a "tree" format */
+/**
+ * Loads the dataset tree by fetching dataset information from the curator API.
+ * Populates the userDatasets, sharedDatasets, and domainDatasets arrays with dataset information.
+ * Generates the dataset tree using the generateTree method of the datasetTree object.
+ * @throws {Error} If there is an error fetching the dataset information.
+ */
const loadDatasetTree = async () => {
const userDatasets = [];
const sharedDatasets = [];
@@ -895,7 +1160,7 @@ const loadDatasetTree = async () => {
let counter = 0;
- // Populate select box with dataset information owned by the user
+ // Create data structure with dataset information owned by the user
if (datasetData.user.datasets.length > 0) {
// User has some profiles
for (const item of datasetData.user.datasets) {
@@ -930,7 +1195,11 @@ const loadDatasetTree = async () => {
}
-// Update the options within the plot type select element, specifically the disabled state
+/**
+ * Updates the plot type select element based on the available plot types.
+ * @param {string|null} analysisId - The ID of the analysis (optional).
+ * @returns {Promise} - A promise that resolves when the plot type select is updated.
+ */
const plotTypeSelectUpdate = async (analysisId=null) => {
// NOTE: Believe updating "disabled" properties triggers the plotTypeSelect "change" element
try {
@@ -949,6 +1218,14 @@ const plotTypeSelectUpdate = async (analysisId=null) => {
}
}
+/**
+ * Renders display cards for user and owner displays.
+ *
+ * @param {Array} userDisplays - The array of user displays.
+ * @param {Array} ownerDisplays - The array of owner displays.
+ * @param {string} defaultDisplayId - The default display ID.
+ * @returns {Promise} - A promise that resolves when the display cards are rendered.
+ */
const renderDisplayCards = async (userDisplays, ownerDisplays, defaultDisplayId) => {
const userDisplaysElt = document.getElementById("user_displays");
const ownerDisplaysElt = document.getElementById("owner_displays");
@@ -977,7 +1254,11 @@ const renderDisplayCards = async (userDisplays, ownerDisplays, defaultDisplayId)
}
}
-// Render the specific series as a sortable list, if it is not already
+/**
+ * Renders the order sortable series.
+ *
+ * @param {string} series - The series to render.
+ */
const renderOrderSortableSeries = (series) => {
const orderContainer = document.getElementById("order_container");
@@ -1024,6 +1305,13 @@ const renderOrderSortableSeries = (series) => {
}
+/**
+ * Renders the owner display card.
+ *
+ * @param {Object} display - The display object.
+ * @param {string} defaultDisplayId - The ID of the default display.
+ * @returns {Promise} - A promise that resolves when the display card is rendered.
+ */
const renderOwnerDisplayCard = async (display, defaultDisplayId) => {
let displayUrl = "";
try {
@@ -1087,6 +1375,12 @@ const renderOwnerDisplayCard = async (display, defaultDisplayId) => {
document.getElementById(`${display.id}_clone`).addEventListener("click", (event) => cloneDisplay(event, display));
}
+/**
+ * Renders a user display card with the given display and default display ID.
+ * @param {Object} display - The display object.
+ * @param {string} defaultDisplayId - The ID of the default display.
+ * @returns {Promise} - A promise that resolves when the display card is rendered.
+ */
const renderUserDisplayCard = async (display, defaultDisplayId) => {
let displayUrl = "";
@@ -1156,7 +1450,11 @@ const renderUserDisplayCard = async (display, defaultDisplayId) => {
document.getElementById(`${display.id}_delete`).addEventListener("click", (event) => curatorApiCallsMixin.deleteDisplay(display.id));
}
-/* Set HTML element value from the plot config value */
+/**
+ * Sets the value of plot elements based on the provided configuration value.
+ * @param {string} classSelector - The class selector for the plot elements.
+ * @param {boolean|string|number} confVal - The configuration value to set.
+ */
const setPlotEltValueFromConfig = (classSelector, confVal) => {
for (const elt of document.getElementsByClassName(classSelector)) {
if (elt.type === "checkbox") {
@@ -1168,7 +1466,11 @@ const setPlotEltValueFromConfig = (classSelector, confVal) => {
}
}
-/* Set disabled state for the given plot type. Also normalize plot type labels */
+/**
+ * Sets the disabled state of a plot type option.
+ * @param {string} plotType - The plot type.
+ * @param {boolean} isAllowed - Whether the plot type is allowed or not.
+ */
const setPlotTypeDisabledState = (plotType, isAllowed) => {
if (plotType === "tsne/umap_dynamic") {
document.getElementById("tsne_dyna_opt").disabled = !isAllowed;
@@ -1178,13 +1480,13 @@ const setPlotTypeDisabledState = (plotType, isAllowed) => {
}
/**
- * Set Select Box Selection By Value
- * Modified to set value and "selected" so nice-select2 extractData() will catch it
- * Taken from https://stackoverflow.com/a/20662180
- * @param eid Element ID
- * @param eval Element value
+ * Sets the selected option in a select box by its value.
+ * @param {string} eid - The ID of the select box element.
+ * @param {string} val - The value of the option to be selected.
*/
const setSelectBoxByValue = (eid, val) => {
+ // Modified to set value and "selected" so nice-select2 extractData() will catch it
+ // Taken from https://stackoverflow.com/a/20662180
const elt = document.getElementById(eid);
for (const i in elt.options) {
if (elt.options[i].value === val) {
@@ -1195,7 +1497,12 @@ const setSelectBoxByValue = (eid, val) => {
}
}
-/* Ensure all elements in this class have the same value */
+/**
+ * Sets up an event listener on elements with the specified class selector.
+ * When the value of any element changes, it copies the new value to all other elements with the same class selector.
+ * Additionally, it updates the disabled state and checked state of the elements based on the triggering element.
+ * @param {string} classSelector - The class selector for the elements to attach the event listener to.
+ */
const setupParamValueCopyEvent = (classSelector) => {
const classElts = document.getElementsByClassName(classSelector)
for (const elt of classElts) {
@@ -1211,7 +1518,10 @@ const setupParamValueCopyEvent = (classSelector) => {
}
}
-/* Setup a fail-fast validation trigger. */
+/**
+ * Sets up validation events for elements with the class "js-plot-req".
+ * @returns {void}
+ */
const setupValidationEvents = () => {
const validationElts = document.getElementsByClassName("js-plot-req");
for (const elt of validationElts ) {
@@ -1219,6 +1529,12 @@ const setupValidationEvents = () => {
}
}
+/**
+ * Updates the options for the private and public analyses select elements.
+ *
+ * @param {Array} privateAnalyses - The array of private analyses.
+ * @param {Array} publicAnalyses - The array of public analyses.
+ */
const updateAnalysesOptions = (privateAnalyses, publicAnalyses) => {
const privateAnalysesElt = document.getElementById("private_analyses");
const publicAnalysesElt = document.getElementById("public_analyses");
@@ -1265,6 +1581,11 @@ const updateAnalysesOptions = (privateAnalyses, publicAnalyses) => {
analysisSelect.update();
}
+/**
+ * Updates the gene options in the gene select element.
+ *
+ * @param {Array} geneSymbols - The array of gene symbols.
+ */
const updateGeneOptions = (geneSymbols) => {
const geneSelectElt = document.getElementById("gene_select");
@@ -1290,7 +1611,9 @@ const updateGeneOptions = (geneSymbols) => {
}
-// Update the params that will comprise the "order" section in post-plot view
+/**
+ * Updates the sortable order of plot param series based on the current selection.
+ */
const updateOrderSortable = () => {
// Get all current plot param series for plotting order and save as a set
const plotOrderElts = document.getElementsByClassName("js-plot-order");
@@ -1341,6 +1664,12 @@ const updateOrderSortable = () => {
}
+/**
+ * Validates the requirements for plotting and updates the UI accordingly.
+ *
+ * @param {Event} event - The event object triggered by the input element.
+ * @returns {void}
+ */
const validateRequirements = (event) => {
const elt = event.target;
// Reset "status" classes
@@ -1451,6 +1780,11 @@ for (const classElt of collapsableElts) {
}
/* --- Entry point --- */
+/**
+ * Handles page-specific login UI updates.
+ * @param {Event} event - The event object.
+ * @returns {Promise} - A promise that resolves when the UI updates are completed.
+ */
const handlePageSpecificLoginUIUpdates = async (event) => {
curatorSpecificNavbarUpdates();
diff --git a/www/js/dataset_curator.v2.js b/www/js/dataset_curator.v2.js
index 463a3b84..9615786b 100644
--- a/www/js/dataset_curator.v2.js
+++ b/www/js/dataset_curator.v2.js
@@ -11,7 +11,11 @@ let geneSelectPost = null;
const plotlyPlots = ["bar", "line", "scatter", "tsne_dyna", "violin"];
const scanpyPlots = ["pca_static", "tsne_static", "umap_static"];
-// Class for methods that are common to all Plotly plot types
+/**
+ * Represents a PlotlyHandler, a class that handles Plotly plots.
+ * @class
+ * @extends PlotHandler
+ */
class PlotlyHandler extends PlotHandler {
constructor(plotType) {
super();
@@ -45,6 +49,11 @@ class PlotlyHandler extends PlotHandler {
plotConfig = {}; // Plot config that is passed to API
+ /**
+ * Clones the display based on the provided configuration.
+ *
+ * @param {Object} config - The configuration object.
+ */
cloneDisplay(config) {
// plotly plots
for (const prop in config) {
@@ -112,6 +121,12 @@ class PlotlyHandler extends PlotHandler {
}
}
+ /**
+ * Creates a plot using the provided dataset ID and analysis object.
+ * @param {string} datasetId - The ID of the dataset.
+ * @param {Object} analysisObj - The analysis object.
+ * @returns {void}
+ */
async createPlot(datasetId, analysisObj) {
// Get data and set up the image area
let plotJson;
@@ -169,6 +184,11 @@ class PlotlyHandler extends PlotHandler {
}
+ /**
+ * Loads the plot HTML by replacing the content of prePlotOptionsElt and postPlotOptionsElt elements.
+ * Populates advanced options for specific plot types.
+ * @returns {Promise} A promise that resolves when the plot HTML is loaded.
+ */
async loadPlotHtml() {
const prePlotOptionsElt = document.getElementById("plot_options_collapsable");
prePlotOptionsElt.replaceChildren();
@@ -198,6 +218,9 @@ class PlotlyHandler extends PlotHandler {
}
}
+ /**
+ * Populates the plot configuration based on the current state of the dataset curator.
+ */
populatePlotConfig() {
this.plotConfig = {}; // Reset plot config
@@ -238,17 +261,32 @@ class PlotlyHandler extends PlotHandler {
}).filter(x => x !== null);
}
+ /**
+ * Sets up the event for copying parameter values.
+ * @async
+ * @function setupParamValueCopyEvent
+ * @returns {Promise}
+ */
async setupParamValueCopyEvent() {
//pass
}
+ /**
+ * Sets up plot-specific events.
+ * @async
+ * @function setupPlotSpecificEvents
+ * @returns {Promise}
+ */
async setupPlotSpecificEvents() {
await setupPlotlyOptions();
}
}
-// Class for methods that are common to all Scanpy plot types
+/**
+ * Represents a ScanpyHandler class that extends PlotHandler.
+ * This class is responsible for creating and manipulating plots for a given dataset using the Scanpy analysis object.
+ */
class ScanpyHandler extends PlotHandler {
constructor(plotType) {
super();
@@ -272,6 +310,10 @@ class ScanpyHandler extends PlotHandler {
plotConfig = {}; // Plot config that is passed to API
+ /**
+ * Clones the display based on the given configuration.
+ * @param {Object} config - The configuration object.
+ */
cloneDisplay(config) {
for (const prop in config) {
setPlotEltValueFromConfig(this.configProp2ClassElt[prop], config[prop]);
@@ -353,6 +395,12 @@ class ScanpyHandler extends PlotHandler {
}
}
+ /**
+ * Creates a plot for a given dataset using the provided analysis object.
+ * @param {string} datasetId - The ID of the dataset.
+ * @param {Object} analysisObj - The analysis object.
+ * @returns {void}
+ */
async createPlot(datasetId, analysisObj) {
let image;
try {
@@ -376,6 +424,10 @@ class ScanpyHandler extends PlotHandler {
}
}
+ /**
+ * Loads the plot HTML by replacing the content of prePlotOptionsElt and postPlotOptionsElt elements.
+ * @returns {Promise} A promise that resolves when the plot HTML is loaded.
+ */
async loadPlotHtml() {
const prePlotOptionsElt = document.getElementById("plot_options_collapsable");
prePlotOptionsElt.replaceChildren();
@@ -387,6 +439,9 @@ class ScanpyHandler extends PlotHandler {
postPlotOptionsElt.innerHTML = await includeHtml("../include/plot_config/post_plot/tsne_static.html");
}
+ /**
+ * Populates the plot configuration based on various elements and values.
+ */
populatePlotConfig() {
this.plotConfig = {}; // Reset plot config
@@ -425,17 +480,28 @@ class ScanpyHandler extends PlotHandler {
}
}
+ /**
+ * Sets up the event for copying parameter values.
+ * @returns {Promise} A promise that resolves when the event setup is complete.
+ */
async setupParamValueCopyEvent() {
//pass
}
+ /**
+ * Sets up plot-specific events.
+ * @returns {Promise} A promise that resolves when the setup is complete.
+ */
async setupPlotSpecificEvents() {
await setupScanpyOptions();
}
}
-// Class for methods that are common to all SVG images
+/**
+ * Represents a SvgHandler, a class that handles SVG plots.
+ * @extends PlotHandler
+ */
class SvgHandler extends PlotHandler {
constructor() {
super();
@@ -452,6 +518,10 @@ class SvgHandler extends PlotHandler {
plotConfig = {colors: {}}; // Plot config to color SVG
+ /**
+ * Clones the display based on the provided configuration.
+ * @param {Object} config - The configuration object.
+ */
cloneDisplay(config) {
// Props are in a "colors" dict
for (const prop in config) {
@@ -467,6 +537,12 @@ class SvgHandler extends PlotHandler {
}
+ /**
+ * Creates a plot for a given dataset and gene symbol.
+ * @param {string} datasetId - The ID of the dataset.
+ * @param {string} geneSymbol - The gene symbol.
+ * @returns {void}
+ */
async createPlot(datasetId, geneSymbol) {
let data;
try {
@@ -480,6 +556,10 @@ class SvgHandler extends PlotHandler {
colorSVG(data, this.plotConfig["colors"]);
}
+ /**
+ * Loads the plot HTML and updates the DOM elements accordingly.
+ * @returns {Promise} A promise that resolves once the plot HTML is loaded and the DOM elements are updated.
+ */
async loadPlotHtml() {
document.getElementById("facet_content").classList.add("is-hidden");
document.getElementById("selected_facets").classList.add("is-hidden");
@@ -494,6 +574,9 @@ class SvgHandler extends PlotHandler {
postPlotOptionsElt.innerHTML = await includeHtml("../include/plot_config/post_plot/svg.html");
}
+ /**
+ * Populates the plot configuration with color values based on user input.
+ */
populatePlotConfig() {
this.plotConfig["colors"] = {}; // Reset plot config
@@ -508,16 +591,28 @@ class SvgHandler extends PlotHandler {
}
+ /**
+ * Sets up an event listener for copying parameter values.
+ * @returns {Promise} A promise that resolves when the event listener is set up.
+ */
async setupParamValueCopyEvent() {
setupParamValueCopyEvent("js-svg-enable-mid");
}
+ /**
+ * Sets up plot-specific events.
+ */
setupPlotSpecificEvents() {
setupSVGOptions();
}
}
+/**
+ * Applies color to an SVG chart based on the provided data and plot configuration.
+ * @param {Object} chartData - The data used to color the chart.
+ * @param {Object} plotConfig - The configuration settings for the chart.
+ */
const colorSVG = (chartData, plotConfig) => {
// I found adding the mid color for the colorblind mode skews the whole scheme towards the high color
const colorblindMode = CURRENT_USER.colorblind_mode;
@@ -596,6 +691,13 @@ const colorSVG = (chartData, plotConfig) => {
}
+/**
+ * Handles the event when a select element is updated in the curatorSpecifcChooseGene function.
+ * If one select element was updated, it ensures the other is updated as well.
+ * It copies data from one select2 to the other and renders the dropdown for the other select2.
+ * If no gene is selected, it disables the plot button and displays an error message.
+ * @param {Event} event - The event object triggered by the select element update.
+ */
const curatorSpecifcChooseGene = (event) => {
// If one select element was updated ensure the other is updated as well
const select2 = event.target.id === "gene_select" ? geneSelect : geneSelectPost;
@@ -648,6 +750,11 @@ const curatorSpecifcChooseGene = (event) => {
document.getElementById("plot_options_s").click();
}
+/**
+ * Creates a plot based on the specified plot type.
+ * @param {string} plotType - The type of plot to create.
+ * @returns {Promise} - A promise that resolves when the plot is created.
+ */
const curatorSpecifcCreatePlot = async (plotType) => {
// Call API route by plot type
if (plotlyPlots.includes(plotType)) {
@@ -665,17 +772,23 @@ const curatorSpecifcCreatePlot = async (plotType) => {
}
+/**
+ * Callback function for curator specific dataset tree.
+ * Creates gene select2 elements for both views.
+ * @returns {void}
+ */
const curatorSpecifcDatasetTreeCallback = () => {
- // Create gene select2 elements for both views
// Not providing the object in the argument could duplicate the nice-select2 structure if called multiple times
geneSelect = createGeneSelectInstance("gene_select", geneSelect);
geneSelectPost = createGeneSelectInstance("gene_select_post", geneSelectPost);
}
+/**
+ * Updates the curator-specific navbar with the current page information.
+ */
const curatorSpecificNavbarUpdates = () => {
- // Update with current page info
document.querySelector("#header_bar .navbar-item").textContent = "Single-gene Curator";
for (const elt of document.querySelectorAll("#primary_nav .menu-list a.is-active")) {
@@ -689,6 +802,11 @@ const curatorSpecificOnLoad = async () => {
// pass
}
+/**
+ * Returns a specific plot style handler based on the given plot type.
+ * @param {string} plotType - The type of plot.
+ * @returns {PlotlyHandler|ScanpyHandler|SvgHandler|null} - The plot style handler.
+ */
const curatorSpecificPlotStyle = (plotType) => {
// include plotting backend options
if (plotlyPlots.includes(plotType)) {
@@ -702,6 +820,11 @@ const curatorSpecificPlotStyle = (plotType) => {
}
}
+/**
+ * Adjusts the plot type for the dataset curator.
+ * @param {string} plotType - The original plot type.
+ * @returns {string} - The adjusted plot type.
+ */
const curatorSpecificPlotTypeAdjustments = (plotType) => {
// ? Move this to class constructor to handle
if (plotType.toLowerCase() === "tsne") {
@@ -713,6 +836,11 @@ const curatorSpecificPlotTypeAdjustments = (plotType) => {
return plotType
}
+/**
+ * Updates the gene options in the curator specific section.
+ *
+ * @param {Array} geneSymbols - The array of gene symbols to update the options with.
+ */
const curatorSpecificUpdateGeneOptions = (geneSymbols) => {
// copy to "#gene_select_post"
const geneSelectEltPost = document.getElementById("gene_select_post");
@@ -726,6 +854,15 @@ const curatorSpecificUpdateGeneOptions = (geneSymbols) => {
}
+/**
+ * Fetches Plotly data for a given dataset, analysis, plot type, and plot configuration.
+ * @param {string} datasetId - The ID of the dataset.
+ * @param {string} analysis - The analysis to perform.
+ * @param {string} plotType - The type of plot to create.
+ * @param {object} plotConfig - The configuration options for the plot.
+ * @returns {Promise} - The fetched Plotly data.
+ * @throws {Error} - If the data fetch fails or an error occurs.
+ */
const fetchPlotlyData = async (datasetId, analysis, plotType, plotConfig) => {
// NOTE: gene_symbol already passed to plotConfig
try {
@@ -742,6 +879,13 @@ const fetchPlotlyData = async (datasetId, analysis, plotType, plotConfig) => {
}
}
+/**
+ * Fetches SVG data for a given dataset and gene symbol.
+ * @param {string} datasetId - The ID of the dataset.
+ * @param {string} geneSymbol - The gene symbol.
+ * @returns {Promise} - The fetched SVG data.
+ * @throws {Error} - If there is an error fetching the SVG data.
+ */
const fetchSvgData = async (datasetId, geneSymbol) => {
try {
const data = await apiCallsMixin.fetchSvgData(datasetId, geneSymbol);
@@ -757,6 +901,16 @@ const fetchSvgData = async (datasetId, geneSymbol) => {
}
};
+/**
+ * Fetches the TSNE image for a given dataset, analysis, plot type, and plot configuration.
+ *
+ * @param {string} datasetId - The ID of the dataset.
+ * @param {string} analysis - The analysis type.
+ * @param {string} plotType - The type of plot.
+ * @param {object} plotConfig - The configuration for the plot.
+ * @returns {Promise} - The fetched data.
+ * @throws {Error} - If there is an error fetching the data or creating the plot image.
+ */
const fetchTsneImage = async (datasetId, analysis, plotType, plotConfig) => {
// NOTE: gene_symbol already passed to plotConfig
try {
@@ -774,6 +928,11 @@ const fetchTsneImage = async (datasetId, analysis, plotType, plotConfig) => {
}
+/**
+ * Renders the color picker for a given series name.
+ *
+ * @param {string} seriesName - The name of the series.
+ */
const renderColorPicker = (seriesName) => {
const colorsContainer = document.getElementById("colors_container");
const colorsSection = document.getElementById("colors_section");
@@ -815,7 +974,10 @@ const renderColorPicker = (seriesName) => {
colorsSection.classList.remove("is-hidden");
}
-/* Set up any Plotly-based plot options and events for the pre- and post- plot views */
+/**
+ * Sets up the options for Plotly.
+ * @returns {Promise} A promise that resolves when the options are set up.
+ */
const setupPlotlyOptions = async () => {
const analysisValue = analysisSelect.selectedOptions.length ? getSelect2Value(analysisSelect) : undefined;
const analysisId = (analysisValue && analysisValue > 0) ? analysisValue : null;
@@ -1026,7 +1188,10 @@ const setupPlotlyOptions = async () => {
}
-/* Set up any Scanpy-based plot options and events for the pre- and post- plot views */
+/**
+ * Sets up the options for Scanpy analysis.
+ * @returns {Promise} A promise that resolves when the setup is complete.
+ */
const setupScanpyOptions = async () => {
const analysisValue = analysisSelect.selectedOptions.length ? getSelect2Value(analysisSelect) : undefined;
const analysisId = (analysisValue && analysisValue > 0) ? analysisValue : null;
@@ -1145,7 +1310,9 @@ const setupScanpyOptions = async () => {
}
-/* Set up any SVG options and events for the pre- and post- plot views */
+/**
+ * Sets up SVG options for dataset curator.
+ */
const setupSVGOptions = () => {
const enableMidColorElts = document.getElementsByClassName("js-svg-enable-mid");
const midColorElts = document.getElementsByClassName("js-svg-mid-color");
@@ -1171,6 +1338,10 @@ const setupSVGOptions = () => {
}
}
+/**
+ * Shows the corresponding subsection based on the selected option in the plot configuration menu.
+ * @param {Event} event - The event triggered by the user's selection.
+ */
const showPostPlotlyParamSubsection = (event) => {
for (const subsection of document.getElementsByClassName("js-plot-config-section")) {
subsection.classList.add("is-hidden");
@@ -1199,7 +1370,14 @@ const showPostPlotlyParamSubsection = (event) => {
event.preventDefault(); // Prevent "link" clicking from "a" elements
}
-// For plotting options, populate select menus with category groups
+/**
+ * Updates the series options in a select element based on the provided parameters.
+ *
+ * @param {string} classSelector - The class selector for the select elements to update.
+ * @param {Array} seriesArray - An array of series names.
+ * @param {boolean} addExpression - Indicates whether to add an expression option.
+ * @param {string} defaultOption - The default option to select.
+ */
const updateSeriesOptions = (classSelector, seriesArray, addExpression, defaultOption) => {
for (const elt of document.getElementsByClassName(classSelector)) {
diff --git a/www/js/user_profile.v2.js b/www/js/user_profile.v2.js
index e2793fb4..4d860e06 100644
--- a/www/js/user_profile.v2.js
+++ b/www/js/user_profile.v2.js
@@ -1,7 +1,12 @@
'use strict';
-/* Creates a Toast-style message in the upper-corner of the screen. */
+/**
+ * Creates a toast notification with the given message and level class.
+ * @param {string} msg - The message to display in the toast notification.
+ * @param {string} [levelClass="is-danger"] - The level class to apply to the toast notification. Defaults to "is-danger".
+ */
const createToast = (msg, levelClass="is-danger") => {
+ // TODO: Merge all the "createToast" functions into one in common.js
const template = `
@@ -107,6 +112,12 @@ document.getElementById("submit_preferences").addEventListener("click", async (e
});
/* --- Entry point --- */
+/**
+ * Handles page-specific login UI updates.
+ *
+ * @param {Event} event - The event object.
+ * @returns {Promise} - A promise that resolves when the UI updates are complete.
+ */
const handlePageSpecificLoginUIUpdates = async (event) => {
// User settings has no "active" state for the sidebar
diff --git a/www/multigene_curator.html b/www/multigene_curator.html
index 655cf268..4ae153f0 100644
--- a/www/multigene_curator.html
+++ b/www/multigene_curator.html
@@ -482,7 +482,6 @@
-