Skip to content

Commit

Permalink
Misc
Browse files Browse the repository at this point in the history
Misc

Refactor base feature widget

M2

Worked

Misc

Allow changing default resolution and normalization in hic
  • Loading branch information
cmdcolin committed Oct 31, 2024
1 parent 2afb715 commit 7db8acc
Show file tree
Hide file tree
Showing 44 changed files with 2,009 additions and 1,672 deletions.
36 changes: 22 additions & 14 deletions packages/app-core/src/ui/App/ViewMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,17 @@ const ViewMenu = observer(function ({
label: 'View order',
type: 'subMenu' as const,
subMenu: [
{
label: 'Move view to top',
icon: KeyboardDoubleArrowUpIcon,
onClick: () => {
session.moveViewToTop(model.id)
},
},
...(session.views.length > 2
? [
{
label: 'Move view to top',
icon: KeyboardDoubleArrowUpIcon,
onClick: () => {
session.moveViewToTop(model.id)
},
},
]
: []),
{
label: 'Move view up',
icon: KeyboardArrowUpIcon,
Expand All @@ -90,13 +94,17 @@ const ViewMenu = observer(function ({
session.moveViewDown(model.id)
},
},
{
label: 'Move view to bottom',
icon: KeyboardDoubleArrowDownIcon,
onClick: () => {
session.moveViewToBottom(model.id)
},
},
...(session.views.length > 2
? [
{
label: 'Move view to bottom',
icon: KeyboardDoubleArrowDownIcon,
onClick: () => {
session.moveViewToBottom(model.id)
},
},
]
: []),
],
},
]
Expand Down
41 changes: 41 additions & 0 deletions packages/core/BaseFeatureWidget/BaseFeatureDetail/BaseCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react'
import {
Accordion,
AccordionDetails,
AccordionSummary,
Typography,
} from '@mui/material'
import { makeStyles } from 'tss-react/mui'

// icons
import ExpandMore from '@mui/icons-material/ExpandMore'

import { BaseCardProps } from '../types'

const useStyles = makeStyles()(theme => ({
expansionPanelDetails: {
display: 'block',
padding: theme.spacing(1),
},
icon: {
color: theme.palette.tertiary.contrastText || '#fff',
},
}))

export default function BaseCard({
children,
title,
defaultExpanded = true,
}: BaseCardProps) {
const { classes } = useStyles()
return (
<Accordion defaultExpanded={defaultExpanded}>
<AccordionSummary expandIcon={<ExpandMore className={classes.icon} />}>
<Typography variant="button">{title}</Typography>
</AccordionSummary>
<AccordionDetails className={classes.expansionPanelDetails}>
{children}
</AccordionDetails>
</Accordion>
)
}
53 changes: 53 additions & 0 deletions packages/core/BaseFeatureWidget/BaseFeatureDetail/CoreDetails.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React from 'react'
// locals
import { toLocale, SimpleFeatureSerialized } from '../../util'
import { BaseProps } from '../types'
import SimpleField from './SimpleField'
import Position from './Position'

export default function CoreDetails(props: BaseProps) {
const { feature } = props
const obj = feature as SimpleFeatureSerialized & {
start: number
end: number
assemblyName?: string
strand: number
refName: string
__jbrowsefmt: {
start?: number
assemblyName?: string
end?: number
refName?: string
name?: string
}
}

const formattedFeat = { ...obj, ...obj.__jbrowsefmt }
const { start, end } = formattedFeat

const displayedDetails: Record<string, any> = {
...formattedFeat,
length: toLocale(end - start),
}

const coreRenderedDetails = {
description: 'Description',
name: 'Name',
length: 'Length',
type: 'Type',
}
return (
<>
<SimpleField
name="Position"
value={<Position {...props} feature={formattedFeat} />}
/>
{Object.entries(coreRenderedDetails)
.map(([key, name]) => [name, displayedDetails[key]])
.filter(([, value]) => value != null)
.map(([name, value]) => (
<SimpleField key={name} name={name} value={value} />
))}
</>
)
}
111 changes: 111 additions & 0 deletions packages/core/BaseFeatureWidget/BaseFeatureDetail/FeatureDetails.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import React from 'react'
import { ErrorBoundary } from '@jbrowse/core/ui/ErrorBoundary'
import { Divider, Typography } from '@mui/material'
import { IAnyStateTreeNode } from 'mobx-state-tree'

// locals
import { getEnv, getSession, SimpleFeatureSerialized } from '../../util'
import { ErrorMessage } from '../../ui'
import { generateTitle } from './util'
import SequenceFeatureDetails from '../SequenceFeatureDetails'
import Attributes from './Attributes'
import BaseCard from './BaseCard'
import CoreDetails from './CoreDetails'

// coreDetails are omitted in some circumstances
const coreDetails = [
'name',
'start',
'end',
'strand',
'refName',
'description',
'type',
]

interface PanelDescriptor {
name: string
Component: React.FC<any>
}

export default function FeatureDetails(props: {
model: IAnyStateTreeNode
feature: SimpleFeatureSerialized
depth?: number
omit?: string[]
descriptions?: Record<string, React.ReactNode>
formatter?: (val: unknown, key: string) => React.ReactNode
}) {
const { omit = [], model, feature, depth = 0 } = props
const { maxDepth } = model
const { mate, name = '', id = '', type = '', subfeatures, uniqueId } = feature
const pm = getEnv(model).pluginManager
const session = getSession(model)

const ExtraPanel = pm.evaluateExtensionPoint('Core-extraFeaturePanel', null, {
session,
feature,
model,
}) as PanelDescriptor | undefined
const m = mate as { start: number; end: number; refName: string } | undefined
return (
<BaseCard title={generateTitle(name, id, type)}>
<Typography>Core details</Typography>
<CoreDetails {...props} />
{m ? (
<>
<Divider />
<Typography>Mate details</Typography>
<CoreDetails
{...props}
feature={{
...m,
start: m.start,
end: m.end,
refName: m.refName,
uniqueId: `${uniqueId}-mate`,
}}
/>
</>
) : null}

<Divider />
<Typography>Attributes</Typography>
<Attributes
attributes={feature}
{...props}
omit={omit}
omitSingleLevel={coreDetails}
/>

<ErrorBoundary FallbackComponent={e => <ErrorMessage error={e.error} />}>
<SequenceFeatureDetails {...props} />
</ErrorBoundary>

{ExtraPanel ? (
<>
<Divider />
<BaseCard title={ExtraPanel.name}>
<ExtraPanel.Component {...props} />
</BaseCard>
</>
) : null}

{depth < maxDepth && subfeatures?.length ? (
<BaseCard title="Subfeatures" defaultExpanded={depth < 1}>
{subfeatures.map((sub, idx) => (
<FeatureDetails
key={JSON.stringify(sub)}
feature={{
...sub,
uniqueId: `${uniqueId}_${idx}`,
}}
model={model}
depth={depth + 1}
/>
))}
</BaseCard>
) : null}
</BaseCard>
)
}
16 changes: 16 additions & 0 deletions packages/core/BaseFeatureWidget/BaseFeatureDetail/Position.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react'
import { assembleLocString } from '../../util'
import { BaseProps } from '../types'

export default function Position(props: BaseProps) {
const { feature } = props
const strand = feature.strand as number
const strandMap: Record<string, string> = {
'-1': '-',
'0': '',
'1': '+',
}
const str = strandMap[strand] ? `(${strandMap[strand]})` : ''
const loc = assembleLocString(feature)
return <>{`${loc} ${str}`}</>
}
Loading

0 comments on commit 7db8acc

Please sign in to comment.