Skip to content

Commit

Permalink
Fix the ability to sort menu items by priority for CascadingMenu (#4554)
Browse files Browse the repository at this point in the history
  • Loading branch information
cmdcolin authored Sep 10, 2024
1 parent 52a87ce commit 055ef35
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 111 deletions.
7 changes: 5 additions & 2 deletions packages/core/pluggableElementTypes/DisplayType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ export default class DisplayType extends PluggableElementBase {
* Indicates that this display type can be a "sub-display" of another type of
* display, e.g. in AlignmentsDisplay, has Pileup and SNPCoverage subDisplays
*/
subDisplay?: unknown
subDisplay?: {
type: string
[key: string]: unknown
}

/**
* The view type the display is associated with
Expand All @@ -32,7 +35,7 @@ export default class DisplayType extends PluggableElementBase {
trackType: string
viewType: string
displayName?: string
subDisplay?: unknown
subDisplay?: { type: string; [key: string]: unknown }
configSchema: AnyConfigurationSchemaType
ReactComponent: AnyReactComponentType
}) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ export function createBaseTrackModel(
{
type: 'subMenu',
label: 'Display types',
priority: -1000,
subMenu: compatDisp.map(d => ({
type: 'radio',
label: pm.getDisplayType(d.type)!.displayName,
Expand Down
96 changes: 50 additions & 46 deletions packages/core/ui/CascadingMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -187,55 +187,59 @@ function CascadingMenuList({
const hasIcon = menuItems.some(m => 'icon' in m && m.icon)
return (
<>
{menuItems.map((item, idx) => {
return 'subMenu' in item ? (
<CascadingSubmenu
key={`subMenu-${item.label}-${idx}`}
popupId={`subMenu-${item.label}`}
title={item.label}
Icon={item.icon}
inset={hasIcon && !item.icon}
onMenuItemClick={onMenuItemClick}
menuItems={item.subMenu}
>
<CascadingMenuList
{...props}
closeAfterItemClick={closeAfterItemClick}
{menuItems
.sort((a, b) => (b.priority || 0) - (a.priority || 0))
.map((item, idx) => {
return 'subMenu' in item ? (
<CascadingSubmenu
key={`subMenu-${item.label}-${idx}`}
popupId={`subMenu-${item.label}`}
title={item.label}
Icon={item.icon}
inset={hasIcon && !item.icon}
onMenuItemClick={onMenuItemClick}
menuItems={item.subMenu}
>
<CascadingMenuList
{...props}
closeAfterItemClick={closeAfterItemClick}
onMenuItemClick={onMenuItemClick}
menuItems={item.subMenu}
/>
</CascadingSubmenu>
) : item.type === 'divider' ? (
<Divider
key={`divider-${JSON.stringify(item)}-${idx}`}
component="li"
/>
</CascadingSubmenu>
) : item.type === 'divider' ? (
<Divider
key={`divider-${JSON.stringify(item)}-${idx}`}
component="li"
/>
) : item.type === 'subHeader' ? (
<ListSubheader key={`subHeader-${item.label}-${idx}`}>
{item.label}
</ListSubheader>
) : (
<CascadingMenuItem
key={`${item.label}-${idx}`}
closeAfterItemClick={closeAfterItemClick}
onClick={'onClick' in item ? handleClick(item.onClick) : undefined}
disabled={Boolean(item.disabled)}
>
{item.icon ? (
<ListItemIcon>
<item.icon />
</ListItemIcon>
) : null}{' '}
<ListItemText
primary={item.label}
secondary={item.subLabel}
inset={hasIcon && !item.icon}
/>
<div style={{ flexGrow: 1, minWidth: 10 }} />
<EndDecoration item={item} />
</CascadingMenuItem>
)
})}
) : item.type === 'subHeader' ? (
<ListSubheader key={`subHeader-${item.label}-${idx}`}>
{item.label}
</ListSubheader>
) : (
<CascadingMenuItem
key={`${item.label}-${idx}`}
closeAfterItemClick={closeAfterItemClick}
onClick={
'onClick' in item ? handleClick(item.onClick) : undefined
}
disabled={Boolean(item.disabled)}
>
{item.icon ? (
<ListItemIcon>
<item.icon />
</ListItemIcon>
) : null}{' '}
<ListItemText
primary={item.label}
secondary={item.subLabel}
inset={hasIcon && !item.icon}
/>
<div style={{ flexGrow: 1, minWidth: 10 }} />
<EndDecoration item={item} />
</CascadingMenuItem>
)
})}
</>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@ export function LinearAlignmentsDisplayMixin(
pluginManager: PluginManager,
configSchema: AnyConfigurationSchemaType,
) {
const lowerPanelDisplays = getLowerPanelDisplays(pluginManager).map(
f => f.stateModel,
)

return types.model({
/**
* #property
* refers to LinearPileupDisplay sub-display model
*/
PileupDisplay: types.maybe(types.union(...lowerPanelDisplays)),
PileupDisplay: types.maybe(
types.union(
...getLowerPanelDisplays(pluginManager).map(f => f.stateModel),
),
),
/**
* #property
* refers to LinearSNPCoverageDisplay sub-display model
Expand Down
12 changes: 4 additions & 8 deletions plugins/alignments/src/LinearAlignmentsDisplay/models/util.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import PluginManager from '@jbrowse/core/PluginManager'

export function getLowerPanelDisplays(pluginManager: PluginManager) {
return (
pluginManager
.getDisplayElements()
// @ts-expect-error
.filter(f => f.subDisplay?.type === 'LinearAlignmentsDisplay')
// @ts-expect-error
.filter(f => f.subDisplay?.lowerPanel)
)
return pluginManager
.getDisplayElements()
.filter(f => f.subDisplay?.type === 'LinearAlignmentsDisplay')
.filter(f => f.subDisplay?.lowerPanel)
}
Original file line number Diff line number Diff line change
Expand Up @@ -479,9 +479,12 @@ export function SharedLinearPileupDisplayMixin(
{
label: 'Color by tag...',
onClick: () => {
getSession(self).queueDialog(doneCallback => [
getSession(self).queueDialog(handleClose => [
ColorByTagDialog,
{ model: self, handleClose: doneCallback },
{
model: self,
handleClose,
},
])
},
},
Expand All @@ -494,20 +497,10 @@ export function SharedLinearPileupDisplayMixin(
trackMenuItems() {
return [
...superTrackMenuItems(),
{
label: 'Filter by...',
icon: FilterListIcon,
priority: -1,
onClick: () => {
getSession(self).queueDialog(doneCallback => [
FilterByTagDialog,
{ model: self, handleClose: doneCallback },
])
},
},

{
label: 'Set feature height...',
priority: -1,
priority: 1,
subMenu: [
{
label: 'Normal',
Expand All @@ -526,20 +519,40 @@ export function SharedLinearPileupDisplayMixin(
{
label: 'Manually set height',
onClick: () => {
getSession(self).queueDialog(doneCallback => [
getSession(self).queueDialog(handleClose => [
SetFeatureHeightDialog,
{ model: self, handleClose: doneCallback },
{
model: self,
handleClose,
},
])
},
},
],
},
{
label: 'Set max height...',
priority: -1,
onClick: () => {
getSession(self).queueDialog(doneCallback => [
getSession(self).queueDialog(handleClose => [
SetMaxHeightDialog,
{ model: self, handleClose: doneCallback },
{
model: self,
handleClose,
},
])
},
},
{
label: 'Filter by...',
icon: FilterListIcon,
onClick: () => {
getSession(self).queueDialog(handleClose => [
FilterByTagDialog,
{
model: self,
handleClose,
},
])
},
},
Expand Down
68 changes: 36 additions & 32 deletions plugins/alignments/src/LinearPileupDisplay/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,34 +269,6 @@ function stateModelFactory(configSchema: AnyConfigurationSchemaType) {
trackMenuItems() {
return [
...superTrackMenuItems(),
{
label: 'Color by...',
icon: ColorLensIcon,
subMenu: [
{
label: 'Pair orientation',
onClick: () => {
self.setColorScheme({ type: 'pairOrientation' })
},
},
{
label: 'Modifications or methylation',
onClick: () => {
getSession(self).queueDialog(doneCallback => [
ModificationsDialog,
{ model: self, handleClose: doneCallback },
])
},
},
{
label: 'Insert size',
onClick: () => {
self.setColorScheme({ type: 'insertSize' })
},
},
...superColorSchemeSubMenuItems(),
],
},

{
label: 'Sort by...',
Expand All @@ -316,7 +288,10 @@ function stateModelFactory(configSchema: AnyConfigurationSchemaType) {
onClick: () => {
getSession(self).queueDialog(handleClose => [
SortByTagDialog,
{ model: self, handleClose },
{
model: self,
handleClose,
},
])
},
},
Expand All @@ -328,6 +303,37 @@ function stateModelFactory(configSchema: AnyConfigurationSchemaType) {
},
],
},
{
label: 'Color by...',
icon: ColorLensIcon,
subMenu: [
{
label: 'Pair orientation',
onClick: () => {
self.setColorScheme({ type: 'pairOrientation' })
},
},
{
label: 'Modifications or methylation',
onClick: () => {
getSession(self).queueDialog(doneCallback => [
ModificationsDialog,
{
model: self,
handleClose: doneCallback,
},
])
},
},
{
label: 'Insert size',
onClick: () => {
self.setColorScheme({ type: 'insertSize' })
},
},
...superColorSchemeSubMenuItems(),
],
},
{
label: 'Group by...',
icon: WorkspacesIcon,
Expand Down Expand Up @@ -374,9 +380,7 @@ function stateModelFactory(configSchema: AnyConfigurationSchemaType) {
return
}

const { bpPerPx } = view

self.setCurrSortBpPerPx(bpPerPx)
self.setCurrSortBpPerPx(view.bpPerPx)
},
{ delay: 1000 },
)
Expand Down

0 comments on commit 055ef35

Please sign in to comment.