Skip to content

Commit

Permalink
Add column URL serialization (#261)
Browse files Browse the repository at this point in the history
* Serialize column visibility model to the URL
* URL serialization tests + don't serialize full object

---------

Co-authored-by: Sebastian Benjamin <sebastiancbenjamin@gmail.com>
  • Loading branch information
hextraza and Sebastian Benjamin authored Jan 17, 2024
1 parent d7df3ca commit 5cdc941
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,6 @@ const VariantTableWidget = observer(props => {
const [fieldTypeInfo, setFieldTypeInfo] = useState<FieldModel[]>([]);
const [allowedGroupNames, setAllowedGroupNames] = useState<string[]>([]);
const [promotedFilters, setPromotedFilters] = useState<Map<string, Filter[]>>(null);
const [columnVisibilityModel, setColumnVisibilityModel] = useState<GridColumnVisibilityModel>({});

const [adapter, setAdapter] = useState<BaseFeatureDataAdapter>(null)

// Active widget ID list to force rerender when a JBrowseUIButton is clicked
Expand All @@ -241,6 +239,10 @@ const VariantTableWidget = observer(props => {
const pageSize = parseInt(urlParams.get('pageSize') || '50');
const [pageSizeModel, setPageSizeModel] = React.useState<GridPaginationModel>({ page, pageSize });

const colVisURLComponent = urlParams.get("colVisModel") || "{}"
const colVisModel = JSON.parse(decodeURIComponent(colVisURLComponent))
const [columnVisibilityModel, setColumnVisibilityModel] = useState<GridColumnVisibilityModel>(colVisModel);

// API call to retrieve the requested features.
useEffect(() => {
const handlePopState = () => {
Expand All @@ -261,9 +263,19 @@ const VariantTableWidget = observer(props => {

setColumns(columns)

const columnVisibilityModel = {}
fields.filter((x) => !x.isHidden).forEach((x) => columnVisibilityModel[x.name] = !!x.isInDefaultColumns)
setColumnVisibilityModel(columnVisibilityModel)
if(JSON.stringify(columnVisibilityModel) === '{}') {
const defaultModel = {};
fields.filter((x) => !x.isHidden).forEach((x) => {
defaultModel[x.name] = !!x.isInDefaultColumns;
});
setColumnVisibilityModel(defaultModel);
} else {
const updatedModel = fields.reduce((acc, field) => {
acc[field.name] = columnVisibilityModel[field.name] === true;
return acc;
}, {});
setColumnVisibilityModel(updatedModel);
}

setFieldTypeInfo(fields)
setAllowedGroupNames(groups)
Expand Down Expand Up @@ -395,6 +407,17 @@ const VariantTableWidget = observer(props => {
}}
onColumnVisibilityModelChange={(model) => {
setColumnVisibilityModel(model)

const trueValuesModel = Object.keys(model).reduce((acc, key) => {
if (model[key] === true) {
acc[key] = true;
}
return acc;
}, {});

const currentUrl = new URL(window.location.href);
currentUrl.searchParams.set("colVisModel", encodeURIComponent(JSON.stringify(trueValuesModel)));
window.history.pushState(null, "", currentUrl.toString());
}}
/>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1813,5 +1813,83 @@ private void testLuceneSearchUI(String sessionId)
waitForElement(Locator.tagWithText("span", "0.029"));

clearFilterDialog("IMPACT equals HIGH,MODERATE");

testLuceneColumnSerialization(sessionId);
}

private void testLuceneColumnSerializationFirstRow() {
WebElement locator = TOP_ROW.findElement(getDriver());

for (WebElement elem : locator.findElements(By.xpath("./child::*"))) {
String value = elem.getText();
if (StringUtils.trimToNull(value) == null)
{
value = "";
}

if (StringUtils.isEmpty(elem.getText())) {
return;
}

switch(elem.getAttribute("aria-colindex"))
{
case "1":
Assert.assertEquals(value, "1");
break;
case "2":
Assert.assertEquals(value, "2");
break;
case "3":
Assert.assertEquals(value, "A");
break;
case "4":
Assert.assertEquals(value, "T");
break;
case "6":
Assert.assertEquals(value, "0.029");
break;
case "7":
Assert.assertEquals(value, "7.292");
break;
case "8":
Assert.assertEquals(value, "HIGH");
break;
}
}
}

private void testLuceneColumnSerialization(String sessionId) {
beginAt("/" + getProjectName() + "/jbrowse-jbrowse.view?session=" + sessionId);
waitAndClick(Locator.tagContainingText("button", "Show all regions in assembly").withClass("MuiButtonBase-root"));
waitAndClick(Locator.tagWithText("p", "No tracks active."));
waitAndClick(Locator.tagWithText("button", "Open track selector"));

Locator l = Locator.tagWithText("span", "TestVCF").withClass("MuiFormControlLabel-label");
waitAndClick(l);
getDriver().findElement(Locator.tag("body")).sendKeys(Keys.ESCAPE); //close modal

openTrackMenuItem("Variant Search", true);
waitAndClick(Locator.tagWithAttribute("button", "aria-label", "Select columns"));

Locator caddScoreToggle = Locator.tagWithAttribute("input", "name", "CADD_PH");
waitForElement(caddScoreToggle);
WebElement parentOfCaddScoreToggle = caddScoreToggle.findElement(getDriver()).findElement(By.xpath("./.."));
parentOfCaddScoreToggle.click();

String colVisModelString = "%257B%2522contig%2522%253Atrue%252C%2522start%2522%253Atrue%252C%2522ref%2522%253Atrue%252C%2522alt%2522%253Atrue%252C%2522variableSamples%2522%253Atrue%252C%2522AF%2522%253Atrue%252C%2522CADD_PH%2522%253Atrue%252C%2522IMPACT%2522%253Atrue%257D";
Assert.assertEquals(getUrlParam("colVisModel"), colVisModelString);

getDriver().navigate().refresh();

waitForElement(TOP_ROW);
Assert.assertEquals(getUrlParam("colVisModel"), colVisModelString);
testLuceneColumnSerializationFirstRow();

waitAndClick(Locator.tagWithText("button", "Search"));
waitAndClick(Locator.tagWithClass("button", "filter-form-select-button"));

waitForElement(TOP_ROW);
Assert.assertEquals(getUrlParam("colVisModel"), colVisModelString);
testLuceneColumnSerializationFirstRow();
}
}

0 comments on commit 5cdc941

Please sign in to comment.