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

Adds the ability to highlight regions using the bookmarks widget #4003

Merged
merged 27 commits into from
Dec 13, 2023

Conversation

carolinebridge
Copy link
Contributor

@carolinebridge carolinebridge commented Oct 20, 2023

demo: https://s3.amazonaws.com/jbrowse.org/code/jb2/bookmark-highlights/index.html

I think this idea could address #599

  • lets users see their bookmarks more easily if they wish (toggle exists, or they can set the opacity to 0)
  • leverages existing bookmarks infrastructure to let users populate highlights with an external data source

leverages code from #3648

includes fix for #3968 that can be cherry picked out if desired

image

@carolinebridge carolinebridge added the enhancement New feature or request label Oct 20, 2023
@carolinebridge carolinebridge self-assigned this Oct 20, 2023
@codecov
Copy link

codecov bot commented Oct 20, 2023

Codecov Report

Attention: 66 lines in your changes are missing coverage. Please review.

Comparison is base (05e1776) 63.24% compared to head (da18c17) 63.16%.
Report is 40 commits behind head on main.

Files Patch % Lines
...gins/grid-bookmark/src/GridBookmarkWidget/model.ts 31.25% 22 Missing ⚠️
...et/components/dialogs/EditHighlightColorDialog.tsx 0.00% 17 Missing ⚠️
...idBookmarkWidget/components/GridBookmarkWidget.tsx 55.00% 9 Missing ⚠️
plugins/grid-bookmark/src/index.ts 20.00% 8 Missing ⚠️
...dBookmarkWidget/components/Highlight/Highlight.tsx 80.00% 4 Missing and 2 partials ⚠️
...get/components/dialogs/HighlightSettingsDialog.tsx 50.00% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4003      +/-   ##
==========================================
- Coverage   63.24%   63.16%   -0.08%     
==========================================
  Files        1045     1045              
  Lines       30616    30695      +79     
  Branches     7314     7329      +15     
==========================================
+ Hits        19362    19388      +26     
- Misses      11084    11138      +54     
+ Partials      170      169       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@carolinebridge
Copy link
Contributor Author

Idea from lincoln:

image

might help navigating bookmarks with labels ... icon would be toggle-able on/off

thoughts?

@cmdcolin
Copy link
Collaborator

yep labels, even displayed textual labels (e.g. for screenshots) but the mouseover is nice too, can be quite useful

@cmdcolin
Copy link
Collaborator

reminds me that the highlight may want to be something that can be svg exported too

…dds new dialog for bulk editing highlight color and session wide options for showing/hiding highlights
@carolinebridge
Copy link
Contributor Author

From meeting:

  • move LGV menu options into submenu
  • storage event listener to sync across tabs
  • disable bulk highlight unless some bookmarks are selected

@carolinebridge carolinebridge marked this pull request as ready for review November 9, 2023 19:54
@carolinebridge carolinebridge changed the title WIP: adding highlights to bookmarks Adds the ability to highlight regions using the bookmarks widget Nov 10, 2023
}

let bookmarkWidget = session.widgets.get('GridBookmark') as GridBookmarkModel
if (!bookmarkWidget) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think it might be worth avoiding doing 'side effects' like addWidget in the body of the react render (e.g. move to useEffect if needed? if its needed at all?)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's needed to access the bookmarks without retrieving directly from the localstorage (i.e. it's going to be using the existing grabs within the bookmarks model instead of re-writing them all)

the motivation here was basically, if you're viewing highlights you're probably going to want to be using the bookmarks widget anyways

i moved it into a useState ? not sure if this resolves your concern but lemme know if you have a better soln for this guy

Copy link
Contributor Author

Choose a reason for hiding this comment

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

reverted cus the linter reminded me why i did it like this in the first place:

React Hook "useState" is called conditionally. React Hooks must be called in the exact same order in every component render thoughts?

Copy link
Collaborator

Choose a reason for hiding this comment

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

move to a useEffect instead of a useState. useEffect is a good way of expressing that "you are doing something as a sideneffect of rendering" which in this case, as part of rendering this component, you are opening the bookmark widget.

Copy link
Collaborator

Choose a reason for hiding this comment

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

also, the linter/runtime warning there is correct: gotta follow the rules of hooks https://legacy.reactjs.org/docs/hooks-rules.html (or new docs https://react.dev/warnings/invalid-hook-call-warning)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sorry, what i meant was using a useEffect has the same linter rule invoked, not that it was exclusive to useState or that the linter was wrong for calling it out. I think it's because I return early if isSessionModelWithWidgets is false

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@cmdcolin lemme know how that looks in the most recent commit

self.bookmarks.remove(bookmark)
}
}
self.setBookmarkedRegions(
Copy link
Collaborator

Choose a reason for hiding this comment

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

any reason for this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

iterating through the array of bookmarks and then removing them was causing issues when clearing all bookmarks -- not all bookmarks were cleared. this function is only used when you attempt to delete bookmarks with nothing selected ('clear' operation)

filtering out bookmarks not present in the session's assemblies then casting the property in setBookmarkedRegions seems to work better.

Copy link
Collaborator

Choose a reason for hiding this comment

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

that is a good bugfix, but it calls into question what was wrong with the previous approach. does the observable-array::remove function not work properly here, or is something not properly observing it

Copy link
Collaborator

Choose a reason for hiding this comment

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

(i can reproduce the issue where 'delete'/clear all was not working before)

className={classes.highlight}
style={{ left, width, background: highlight }}
>
{showBookmarkLabels ? (
Copy link
Collaborator

Choose a reason for hiding this comment

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

you could consider drawing the text right onto the display. this would make it easier to see at a glance, and allow screenshot-ability compared to requiring a mouseover

Copy link
Contributor Author

Choose a reason for hiding this comment

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

do you mean have the label displayed at all times? is that desirable?

Copy link
Collaborator

Choose a reason for hiding this comment

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

IMO, yes. the bookmark icon feels odd to me, especially if there is not any label. i think it may look better for there to be no icon, and text displayed always, unless showBookmarkLabels is false

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure I agree with this --

You can turn the bookmark icon 'off' for the express reason of "I don't want this in my screenshots". Being enabled by default communicates to the user "what" the highlighted area is, and enables the label quick access. The icon, for this purpose, was requested by Lincoln when I first demo'd it to him (it looked like the first screenshot on this PR).

If a user really wants their labels in their screenshots, delayed screen captures exist. I think having so much text like that, especially for a heavy "annotator", would be obtuse.

Mostly though, I really don't see having the text displayed always as a better-looking option...I am having trouble conceiving what you might be imagining, here's a mockup?:
image
image

Maybe draft for me what you'd like to see or describe some more details.

Copy link
Collaborator

Choose a reason for hiding this comment

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

there are similar challenges with overlapping feature labels. I believe such overlapping text could be remedied in most cases by adding ellipses and/or perhaps adding y-axis dodging (so that they avoid being on the same text row)

i actually prefer the text being there despite overlaps, because it gives me a quick overview, without having to mouseover many things. it is up to you though

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll leave it as is for now...I think resolving the overlaps with an ellipses negates the idea of having an overview of the labels (because you can't read them in their entirety), and if you're looking for a big picture overview, you can see all your labels in the widget. Y-axis dodging could resolve for some cases, but I don't think it would scale well, because in higher density you're adding a lot of vertical space clutter.

'GridBookmarkWidget',
'GridBookmark',
) as GridBookmarkModel
bookmarks.current = newBookmarkWidget.bookmarks
Copy link
Collaborator

Choose a reason for hiding this comment

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

i think that this code points to a thing where the fact that the bookmarks are stored on the widget, and therefore needing the widget to be open, is a bit awkward.

one alternative approach would be to extend the session model (via Core-extendSession perhaps) and add the functions that read and manipulate the highlight state directly onto the session model. then, the highlights can be displayed regardless of whether the grid bookmark widget is opened.

i would say this change is not necessarily required for this PR to go forward but it could be worth considering for the future

Copy link
Collaborator

Choose a reason for hiding this comment

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

(note that one reason i say it's not strictly required is that the bookmark widget does not strictly need to even be "open" as in visible, as we have the concept of the widget state being retained in the session despite it being "closed", at least for now...xref #3538)

@cmdcolin
Copy link
Collaborator

cmdcolin commented Dec 13, 2023

this is sort of a misc proposal, but I tried out a proposal for moving basically all the buttons in the 'header' of the bookmark widget into a dropdown hamburger menu

https://github.com/GMOD/jbrowse-components/compare/bookmark-highlights...bookmark-highlights-cmd2?expand=1

example screenshot

image

it also adds a edit icon to all the label fields, to try to make it more abundantly clear that the labels are editable, and then we don't need the 'alert' box in the header. it removes the 'editable:true' on the label column because hitting enter triggers the dialog, but we could re-enable the editable:true if it didn't trigger the dialog on enter perhaps, but now this just makes editing always needs the dialog

@cmdcolin
Copy link
Collaborator

cmdcolin commented Dec 13, 2023

@@ -175,6 +221,16 @@ export default function f(_pluginManager: PluginManager) {
.actions(self => ({
afterAttach() {
const key = localStorageKeyF()
function handler(e: StorageEvent) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

tested and works :) I think this should be good to go

@carolinebridge
Copy link
Contributor Author

re: bookmarks-highlights-cmd2

I don't mind the hamburger menu, but I think the edit icon doesn't "fit" in the table cells. Longer labels seem to cut it off on the default load. Might be better to put it in the column header, if anywhere. I don't mind removing the single click edit if it felt unnatural.

@cmdcolin
Copy link
Collaborator

what if assembly column was hidden by default? the majority use case would be showing 'one genome assembly's worth of bookmarks at a time' and this would provide more room for edit icon

@carolinebridge
Copy link
Contributor Author

I mostly think the edit icon looks out of place in the cell, here's what the table looks like at the default size with the assembly column hidden:

image

I don't mind hiding that column when one assembly is shown, but I'm not sure that solves the awkwardness.

@cmdcolin
Copy link
Collaborator

with the "classes.cell" css class is added to this div, it will more accurately change the cell to have ellipses instead of cutting off the icon like in the above screenshot. added that as a push to branch

const [widths, setWidths] = useState([
50,
40,
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think that the checkbox cell is still width ~50 so this change may not be accurate. can see in hovering the lines are mismatched

image

@cmdcolin
Copy link
Collaborator

i'd be fine with removing the icon for now also...maybe can just do that and merge the hamburger menu in, and then ponder other edit icon stuff later

@cmdcolin cmdcolin force-pushed the bookmark-highlights branch from 19b7990 to 219b45a Compare December 13, 2023 15:28
@cmdcolin
Copy link
Collaborator

i think good to go, possible add on here #4130

@cmdcolin
Copy link
Collaborator

I had to move some of the 'unit tests' into integration level tests to allow the new usage of session.queueDialog from the hamburger menu. This is because session.queueDialog will not render the dialog properly in unit tests, because the app-level processing that actually react-renders the dialog queue is not hooked up

@cmdcolin cmdcolin merged commit 06448e9 into main Dec 13, 2023
10 checks passed
@cmdcolin cmdcolin deleted the bookmark-highlights branch December 13, 2023 16:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants