Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DATAUP-639 dynamic dropdown fixes #2911

Merged
merged 7 commits into from Apr 29, 2022
Merged

Conversation

briehl
Copy link
Member

@briehl briehl commented Apr 27, 2022

Description of PR purpose/changes

This makes progress toward fixing some issues with the dynamic dropdown. It specifically addresses how values get displayed on load or on update.

There are a few issues here.
First, when the dropdown loads, if there's an initialValue given, it creates and selects an initial option. The problem is, there's no display info. For the taxonomy id case, it gets an id value, say, 12345. To fill out the display template, it needs a scientific_name and ncbi_taxon_id. Without those, the field would render in as "NCBI Tax ID undefined: undefined".

Second, when doing a search that reveals the same value, the actual answer would never get updated - a search that came back with tax id 12345 would always display that "undefined" stuff.

The main problem is that Select2 is a big jerk and doesn't like to change its Option data. There've been Select2 tickets existing since like 2014. (i.e.: select2/select2#2830) The only solutions are semi-horrible hacks, so that's what happen here. Fun!

The core fixes introduced here are:

  1. The dynamic dropdown now emits a newDisplayValue along with newValue on the changed bus message. Not consumed anywhere yet.
  2. The dropdown consumes a initialDisplayValue in its config, expected to be an object with the keys from the description_template config expected.
  3. If an initialDisplayValue is not included, it defaults to the actual value. Not any worse than showing undefineds?

Jira Ticket / Issue

Related Jira ticket: https://kbase-jira.atlassian.net/browse/DATAUP-639

  • Added the Jira Ticket to the title of the PR (e.g. DATAUP-69 Adds a PR template)

Testing Instructions

  • Details for how to test the PR:
  • Tests pass locally and in GitHub Actions
  • Changes available by spinning up a local narrative and navigating to X to see Y

Dev Checklist:

  • My code follows the guidelines at https://sites.google.com/lbl.gov/trussresources/home?authuser=0
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • (JavaScript) I have run Prettier and ESLint on changed code manually or with a git precommit hook
  • Any dependent changes have been merged and published in downstream modules

Updating Version and Release Notes (if applicable)

@@ -543,7 +543,7 @@ def test_get_all_job_states__ignore_refresh_flag(self):
states,
)

## get_job_states_by_cell_id
# get_job_states_by_cell_id
Copy link
Member Author

Choose a reason for hiding this comment

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

This made my flake8 freak out. Not sure how that happened.

value: undefined,
},
userId = runtime.userId();
descriptionFields: new Set(),
Copy link
Member Author

Choose a reason for hiding this comment

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

This will hold the fields used in the description template. So if the template is:

NCBI Taxon ID: {{ncbi_taxon_id}}: {{scientific_name}}

it will have the values ncbi_taxon_id and scientific_name.

const newOption = new Option(value, value, true, true);
$(control).append(newOption).trigger('change');
if (model.value) {
const selectorValue = value.replace(/"/g, '\\"').replace(/'/g, "\\'");
Copy link
Member Author

Choose a reason for hiding this comment

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

This is from an issue with the FTP staging version of the dropdown - if there are quotes in the value (say, a file name with quotes in it), it goes all kinds of wonky. Need to be escaped.

Comment on lines +139 to +144
const dataAdapter = $(control).data('select2').dataAdapter;
const newOption = dataAdapter.option(
Object.assign({ id: model.value, value: model.value }, displayValue)
);
dataAdapter.addOptions(newOption);
$(control).val(value).trigger('change');
Copy link
Member Author

Choose a reason for hiding this comment

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

From some deep diving in Select2 code and docs, this creates a new option with all of the data that the Select2 option would otherwise see from a successful search, and lets Select2 do the usual rendering.

* @param {string} searchTerm
* @returns Array
*/
async function fetchFtpStagingData(searchTerm) {
Copy link
Member Author

@briehl briehl Apr 27, 2022

Choose a reason for hiding this comment

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

Popped this out of the fetchData function, effectively unchanged otherwise.

@@ -272,7 +300,7 @@ define([
// could check here that each item is a map? YAGNI
obj = flattenObject(obj);
if (!('id' in obj)) {
obj.id = _index; // what the fuck
obj.id = _index;
Copy link
Member Author

Choose a reason for hiding this comment

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

Every object passed to Select2 needs a unique id field.

Copy link
Collaborator

Choose a reason for hiding this comment

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

if only the original author of that line had read the docs!

* @returns {JQueryElement} a jQuery-wrapped div element
*/
function formatFtpStagingDisplay(fileData) {
return $(
Copy link
Member Author

Choose a reason for hiding this comment

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

Took this out of the formatObjectDisplay function.
Really, the StagingService dropdown could be its own input, or a subclass of this one if we were doing object-oriented things properly.

else {
formattedString = retObj.text || retObj.id;
}
// and squash the result in a jQuery object with a div.
Copy link
Member Author

Choose a reason for hiding this comment

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

Select2 wants either a string (which will be put in as a textContent field to avoid XSS things) or a jquery element. We do our own escaping with util/string, so there should be less danger.

@lgtm-com
Copy link

lgtm-com bot commented Apr 27, 2022

This pull request introduces 2 alerts when merging 61e252f into 3cb1d2a - view on LGTM.com

new alerts:

  • 2 for Incomplete string escaping or encoding

delay: 250,
processResults: (data) => {
// update the currently selected one if applicable
const currentData = dropdown.select2('data')[0];
Copy link
Member Author

Choose a reason for hiding this comment

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

This fixes the issue where display data doesn't get updated. So if you start with undefined stuff in the currently selected option, then do a search that brings in a matching value, this will update that option with data from the service.

.on('change', () => {
doChange();
const data = dropdown.select2('data');
return doChange(data ? data[0] : {});
Copy link
Member Author

Choose a reason for hiding this comment

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

Send the data object along when doing a change, so we save the display value as well.

const control = ui.getElement('input-container.input');
if (control) {
$(control).select2('destroy').html('');
}
Copy link
Member Author

Choose a reason for hiding this comment

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

Select2 puts all kinds of things in all kinds of places in the DOM. We need to specifically call destroy to make sure it all goes away.

@codecov
Copy link

codecov bot commented Apr 27, 2022

Codecov Report

Merging #2911 (63e0348) into develop (8599a3f) will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff            @@
##           develop    #2911   +/-   ##
========================================
  Coverage    73.20%   73.20%           
========================================
  Files           36       36           
  Lines         3896     3896           
========================================
  Hits          2852     2852           
  Misses        1044     1044           

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update dfe7696...63e0348. Read the comment docs.

Copy link
Collaborator

@ialarmedalien ialarmedalien left a comment

Choose a reason for hiding this comment

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

LGTM

@lgtm-com
Copy link

lgtm-com bot commented Apr 27, 2022

This pull request introduces 2 alerts when merging a666982 into dd9200d - view on LGTM.com

new alerts:

  • 2 for Incomplete string escaping or encoding

@lgtm-com
Copy link

lgtm-com bot commented Apr 28, 2022

This pull request introduces 2 alerts when merging 63e0348 into dfe7696 - view on LGTM.com

new alerts:

  • 2 for Incomplete string escaping or encoding

@sonarcloud
Copy link

sonarcloud bot commented Apr 28, 2022

SonarCloud Quality Gate failed.    Quality Gate failed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot E 2 Security Hotspots
Code Smell A 1 Code Smell

No Coverage information No Coverage information
0.0% 0.0% Duplication

@ialarmedalien ialarmedalien merged commit 5ced514 into develop Apr 29, 2022
@ialarmedalien ialarmedalien deleted the DATAUP-639-dyndrop-2 branch April 29, 2022 14:30
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.

None yet

2 participants