Skip to content

Move TargetedMS QC/chart UI off ExtJS to plain JS + HTML - #1257

Open
ankurjuneja wants to merge 17 commits into
developfrom
fb_1249_extJS
Open

Move TargetedMS QC/chart UI off ExtJS to plain JS + HTML#1257
ankurjuneja wants to merge 17 commits into
developfrom
fb_1249_extJS

Conversation

@ankurjuneja

@ankurjuneja ankurjuneja commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Rationale

We are gradually removing our dependency on ExtJS. ExtJS is old, heavy, and something we want to stop using. Each of these screens used ExtJS only as a wrapper around plain data or existing non-ExtJS chart code, so we can swap in simple HTML, plain JavaScript, and jQuery without changing what the user sees. This makes the code lighter, easier to read, and easier to maintain.

Related Pull Requests

Changes

  • Trace metric dialog (resources/web/PanoramaPremium/window/AddNewTraceMetricWindow.js)
  • Pareto plot (webapp/TargetedMS/js/ParetoPlotPanel.js)
  • Calibration curve (webapp/TargetedMS/js/CalibrationCurve.js)
  • Summary charts (src/org/labkey/targetedms/view/summaryChartsView.jsp)

Comment thread src/org/labkey/targetedms/view/calibrationCurve.jsp Outdated
Comment thread resources/web/PanoramaPremium/window/AddNewTraceMetricWindow.js
const title = op === 'insert' ? 'Add New Trace Metric' : 'Edit Trace Metric';

// In update mode, pick the mode based on the stored values; default to the time-value mode.
const isTraceValueMode = op === 'update' && metric.TraceValue > 0;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The check on line 79 allows zeros when saving, but this treats them as a sentinel. Probably best to make line 79 ensure a positive value, which matches the old validation.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Further/related concern:

Issue: const isTraceValueMode = op === 'update' && metric.TraceValue > 0; picks the radio button by looking at TraceValue alone, but the server resolves the opposite way — TargetedMSManager line ~2910 checks timeValueOption first and only falls through to traceValue when it is null.

Why it matters: Every trace metric saved by the old dialog can have both configurations populated, because the old saveNewMetric wrote only the chosen mode's columns and never cleared the other. Opening such a row now shows the trace-value radio selected with a trace threshold filled in, while the plot on the dashboard is still being computed from TimeValueOption/MinTimeValue/MaxTimeValue. That is the same class of "UI shows one thing, server does another" bug the rest of this change sets out to eliminate.

Suggestion: const isTraceValueMode = op === 'update' && !metric.TimeValueOption && metric.TraceValue > 0;

return String(a.TextId).localeCompare(String(b.TextId));
});
let html = '<option value="">-- Select trace --</option>';
traces.forEach(function(row) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Low priority, but if the previously saved value is no longer present, it won't be in the list. The old code always added the saved value. We could do the same here.

const metricName = $('#lk-trace-metric-name').val().trim();
checkMetricNameExists(metricName, function(exists) {
if (exists) {
showError('A metric with the name "' + LABKEY.Utils.encodeHtml(metricName) + '" already exists. Please choose a different name.');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

showError uses .text() so this will be double-encoded. Remove the encoding here.

Comment thread webapp/TargetedMS/js/CalibrationCurve.js Outdated
Comment thread src/org/labkey/targetedms/view/summaryChartsView.jsp Outdated
Comment on lines +387 to +390
areaElement.style.width = parseInt(widthInput.value) + 'px';
areaElement.style.height = parseInt(heightInput.value) + 'px';
timeElement.style.width = parseInt(widthInput.value) + 'px';
timeElement.style.height = parseInt(heightInput.value) + 'px';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally we'd handle a NaN as type="number" isn't particularly strict.

this.queryError.setVisible(true);
}
});
LABKEY.Query.saveRows({

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my local testing, this can be sluggish to save. There's no feedback for the user while it's working, which led me to click on Save a second time, which then produced a key violation. This change presumably hasn't impacted the perf, but it would be nice to show a spinner and disable the buttons to avoid a double-submit.

Comment thread src/org/labkey/targetedms/view/calibrationCurve.jsp Outdated
public void addClientDependencies(ClientDependencies dependencies)
{
dependencies.add("Ext4");
dependencies.add("Ext4"); // still needed by QCMetricConfigLoader.js

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like it's just for JSON parsing. Can we migrate that?

@labkey-jeckels labkey-jeckels left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor suggestions but not need for further review unless you want it.

Comment thread resources/web/PanoramaPremium/window/AddNewAnnotationMetricWindow.js Outdated
Comment thread resources/web/PanoramaPremium/window/AddNewTraceMetricWindow.js Outdated
Comment on lines +103 to +104
// The ExtJS stores prepended "All"/"None" entries, so the original visibility checks were
// count-based (e.g. store.count() > 2). Translate those to list-size checks here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this important post-migration?

Comment thread webapp/TargetedMS/js/CalibrationCurve.js Outdated
const title = op === 'insert' ? 'Add New Trace Metric' : 'Edit Trace Metric';

// In update mode, pick the mode based on the stored values; default to the time-value mode.
const isTraceValueMode = op === 'update' && metric.TraceValue > 0;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Further/related concern:

Issue: const isTraceValueMode = op === 'update' && metric.TraceValue > 0; picks the radio button by looking at TraceValue alone, but the server resolves the opposite way — TargetedMSManager line ~2910 checks timeValueOption first and only falls through to traceValue when it is null.

Why it matters: Every trace metric saved by the old dialog can have both configurations populated, because the old saveNewMetric wrote only the chosen mode's columns and never cleared the other. Opening such a row now shows the trace-value radio selected with a trace threshold filled in, while the plot on the dashboard is still being computed from TimeValueOption/MinTimeValue/MaxTimeValue. That is the same class of "UI shows one thing, server does another" bug the rest of this change sets out to eliminate.

Suggestion: const isTraceValueMode = op === 'update' && !metric.TimeValueOption && metric.TraceValue > 0;

Comment thread src/org/labkey/targetedms/view/summaryChartsView.jsp Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants