Skip to content

Commit

Permalink
Merge pull request #1496 from nextstrain/feat/web-help-tips
Browse files Browse the repository at this point in the history
  • Loading branch information
ivan-aksamentov authored Jul 2, 2024
2 parents 5a870c1 + 8bc97a6 commit 3de1907
Show file tree
Hide file tree
Showing 8 changed files with 186 additions and 66 deletions.
18 changes: 10 additions & 8 deletions packages/nextclade-web/src/components/Common/InfoButton.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { PropsWithChildren } from 'react'
import { Button as ButtonBase, CardBody } from 'reactstrap'
import { Button as ButtonBase, ButtonProps, CardBody } from 'reactstrap'
import styled, { useTheme } from 'styled-components'
import { FaInfo as InfoIcon } from 'react-icons/fa6'
import { useTranslationSafe } from 'src/helpers/useTranslationSafe'
Expand All @@ -12,21 +12,22 @@ import {
useRole,
FloatingPortal,
autoPlacement,
shift,
} from '@floating-ui/react'

export interface InfoButtonProps {
export interface InfoButtonProps extends Omit<ButtonProps, 'size'> {
size?: number
}

export function InfoButton({ size = 18, children }: PropsWithChildren<InfoButtonProps>) {
export function InfoButton({ size = 20, children, ...restProps }: PropsWithChildren<InfoButtonProps>) {
const { t } = useTranslationSafe()
const theme = useTheme()

const { state: isOpen, toggle, setState: setIsOpen } = useToggle(false)
const { refs, context, floatingStyles } = useFloating({
open: isOpen,
onOpenChange: setIsOpen,
middleware: [autoPlacement()],
middleware: [shift({ padding: 5 }), autoPlacement()],
})
const dismiss = useDismiss(context)
const focus = useFocus(context)
Expand All @@ -41,6 +42,7 @@ export function InfoButton({ size = 18, children }: PropsWithChildren<InfoButton
title={t('Click to get help information')}
$size={size}
{...getReferenceProps({ onClick: toggle })}
{...restProps}
>
<Icon color={theme.primary} size={size * 0.66} />
</Button>
Expand All @@ -59,9 +61,6 @@ export function InfoButton({ size = 18, children }: PropsWithChildren<InfoButton

const Floating = styled.div`
z-index: 1005;
width: 500px;
max-width: 80vw;
max-height: 80vh;
`

const Card = styled.div`
Expand All @@ -70,10 +69,13 @@ const Card = styled.div`
border-radius: 5px;
height: 100%;
background-color: ${(props) => props.theme.bodyBg};
max-height: 80vh;
max-width: 80vw;
width: 500px;
`

const Button = styled.button<{ $size?: number }>`
display: flex;
display: inline-flex;
width: ${(props) => props.$size}px;
height: ${(props) => props.$size}px;
border-radius: ${(props) => props.$size}px;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,11 @@ export function SelectDatasetHelp() {
)}
</p>

<p>
{t('Learn more about Nextclade datasets in the {{documentation}}')}
<LinkExternal href="https://docs.nextstrain.org/projects/nextclade/en/stable/user/datasets.html">
<p className="p-0 m-0 small">
{t('Learn more in Nextclade {{documentation}}')}
<LinkExternal href="https://docs.nextstrain.org/projects/nextclade/en/stable">
{t('documentation')}
</LinkExternal>
{t('.')}
</p>
</InfoButton>
)
Expand Down
81 changes: 81 additions & 0 deletions packages/nextclade-web/src/components/Help/SelectGeneHelp.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import React from 'react'
import { HelpTipsColumnSeqViewGeneLegend } from 'src/components/Results/HelpTips/HelpTipsColumnSeqViewGeneLegend'
import { HelpTipsColumnSeqViewNucLegend } from 'src/components/Results/HelpTips/HelpTipsColumnSeqViewNucLegend'
import { useTranslationSafe } from 'src/helpers/useTranslationSafe'
import { InfoButton } from 'src/components/Common/InfoButton'
import { LinkExternal } from 'src/components/Link/LinkExternal'

export function SelectGeneHelp() {
const { t } = useTranslationSafe()

return (
<InfoButton color="link">
<h5>{t('Select a genetic feature.')}</h5>

<p>
{t(
'This allows to switch sequence views between nucleotide sequence and peptides (translated CDSes; only available if the dataset provides a genome annotation).',
)}
</p>

<hr />

<p>
{t(
'Each row of the table displays a schema of the corresponding sequence, highlighting the differences relative to the target selected in the "Relative to" dropdown.',
)}
</p>

<hr />

<h5>{t('Nucleotide Sequence mode')}</h5>

<p>
{t(
'In "Nucleotide Sequence" mode, the whole nucleotide sequence is shown. Line markers represent nucleotide mutations. They are colored by the resulting (query) nucleotide:',
)}
</p>

<HelpTipsColumnSeqViewNucLegend />

<p>
{t('Mouse hover on a mutation marker to show details of that mutation and its neighborhood in the alignment.')}
<br />
{t("Unsequenced regions at the 5' and 3' end are indicated as light gray areas on both ends.")}
<br />
{t('For a mapping between positions in the sequence and genes, see Genome Annotation view below the table.')}
</p>

<hr />

<h5>{t('Peptide/protein mode')}</h5>

<p>
{t(
'When a CDS is selected, each row displays a schema of the corresponding translated amino acid sequence by highlighting the differences to the corresponding peptide in the reference/target. Note that the CDS might be split into multiple segments or be located on the reverse strand.',
)}
<br />
{t(
'Line markers on sequence views represent amino acid mutations colored by the resulting (query) amino acid:',
)}
</p>

<HelpTipsColumnSeqViewGeneLegend />

<p>
{t('Note: Sometimes mutations are so close to each other that they overlap.')}
<br />
{t('Note: Positions are 1-based.')}
</p>

<hr />

<p className="p-0 m-0 small">
{t('Learn more in Nextclade {{documentation}}')}
<LinkExternal href="https://docs.nextstrain.org/projects/nextclade/en/stable">
{t('documentation')}
</LinkExternal>
</p>
</InfoButton>
)
}
58 changes: 58 additions & 0 deletions packages/nextclade-web/src/components/Help/SelectRefNodeHelp.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React from 'react'
import { useTranslationSafe } from 'src/helpers/useTranslationSafe'
import { InfoButton } from 'src/components/Common/InfoButton'
import { LinkExternal } from 'src/components/Link/LinkExternal'
import { Ul, Li } from 'src/components/Common/List'

export function SelectRefNodeHelp() {
const { t } = useTranslationSafe()

return (
<InfoButton color="link">
<h5>{t('Select target for mutation calling.')}</h5>
<p>
{t(
'The sequence view below shows differences between each query sequence and a "comparison target" that can be selected using this dropdown. Possible options are:',
)}
</p>

<Ul>
<Li>{t('"Reference" - shows mutations relative to the reference sequence (as defined in the dataset).')}</Li>
<Li>
{t(
'"Parent" - shows private mutations, i.e. mutations relative to the parent (nearest) node of the reference tree to which the query sample has been attached to during phylogenetic placement.',
)}
</Li>
<Li>
{t(
'"Clade founder" - shows mutations relative to the founder of the clade that has been assigned to the query sample. Note that queries from different clades will be compared with different targets in this case.',
)}
</Li>
<Li>
{t(
'Entries of format "\'<attribute>\' founder" show mutations relative to the founder node of a particular clade-like attribute (if any are defined in the dataset). Dataset authors may choose to exclude certain attributes.',
)}
</Li>
<Li>
{t(
'Any additional entries show mutations relative to the node(s) found according to the custom search criteria (if any defined in the dataset). If the query sample does not match search criteria, then "{{ notApplicable }}" will be displayed.',
{ notApplicable: t('Not applicable') },
)}
</Li>
</Ul>

<p>
{t(
'Switching the target will change mutations displayed in the sequence views as well as in the "Mut" column of the table and its mouseover tooltip.',
)}
</p>

<p className="p-0 m-0 small">
{t('Learn more in Nextclade {{documentation}}')}
<LinkExternal href="https://docs.nextstrain.org/projects/nextclade/en/stable">
{t('documentation')}
</LinkExternal>
</p>
</InfoButton>
)
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react'
import styled from 'styled-components'

import { AMINOACID_COLORS } from 'src/helpers/getAminoacidColor'
import { Col, Row } from 'reactstrap'

Expand All @@ -13,6 +12,7 @@ export const Legend = styled.div`

export const LegendItem = styled.div`
display: flex;
margin: 3px;
`

export const LegendColorBox = styled.span`
Expand Down Expand Up @@ -41,7 +41,7 @@ export function splitToColumns(obj: { [key: string]: string }, colSize: number)
}

export function HelpTipsColumnSeqViewGeneLegend() {
const columns = splitToColumns(AMINOACID_COLORS, 4)
const columns = splitToColumns(AMINOACID_COLORS, 5)

return (
<Legend>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import React from 'react'
import styled from 'styled-components'
import { Col, Row } from 'reactstrap'

import { NUCLEOTIDE_COLORS } from 'src/helpers/getNucleotideColor'
import { splitToColumns } from './HelpTipsColumnSeqViewGeneLegend'

const SIZE = 20

export const Legend = styled(Row)`
width: 100%;
margin-bottom: 10px;
//margin-bottom: 10px;
`

export const LegendItem = styled(Col)`
display: flex;
margin: 3px;
`

export const LegendColorBox = styled.span`
Expand All @@ -25,14 +26,23 @@ export const LegendColorBox = styled.span`
`

export function HelpTipsColumnSeqViewNucLegend() {
const columns = splitToColumns(NUCLEOTIDE_COLORS, 5)

return (
<Legend>
{Object.entries(NUCLEOTIDE_COLORS).map(([nuc, color]) => (
<LegendItem key={nuc}>
<LegendColorBox color={color} />
{nuc}
</LegendItem>
))}
<Row>
{columns.map((col, i) => (
// eslint-disable-next-line react/no-array-index-key
<Col key={i}>
{Object.entries(col).map(([aa, color]) => (
<LegendItem key={aa}>
<LegendColorBox color={color} />
{aa}
</LegendItem>
))}
</Col>
))}
</Row>
</Legend>
)
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react'
import HelpTipsColumnSeqView from 'src/components/Results/HelpTips/HelpTipsColumnSeqView.mdx'
import { SelectGeneHelp } from 'src/components/Help/SelectGeneHelp'
import { SelectRefNodeHelp } from 'src/components/Help/SelectRefNodeHelp'
import { RefNodeSelector } from 'src/components/Results/RefNodeSelector'
import { ButtonHelpStyled } from 'src/components/Results/ResultsTableStyle'
import { useTranslationSafe } from 'src/helpers/useTranslationSafe'
Expand All @@ -19,21 +20,25 @@ export function SequenceViewColumnHeader() {
<FlexLarge>
<FlexOuter>
<DropdownWrapper className="ml-auto">
<span className="pb-1 px-1">{t('Genetic feature')}</span>
<span className="pb-1 px-1 d-flex">
<span className="my-auto">{t('Genetic feature')}</span>
<span className="my-auto">
<SelectGeneHelp />
</span>
</span>
<SequenceSelector />
</DropdownWrapper>
<DropdownWrapper className="mr-auto">
<span className="pb-1 px-1">{t('Relative to')}</span>
<span className="pb-1 px-1 d-flex">
<span className="my-auto">{t('Relative to')}</span>
<span className="my-auto">
<SelectRefNodeHelp />
</span>
</span>
<RefNodeSelector />
</DropdownWrapper>
</FlexOuter>
</FlexLarge>

<FlexSmall className="mr-2">
<ButtonHelpStyledLeft identifier="btn-help-col-seq-view" tooltipWidth="600px">
<HelpTipsColumnSeqView />
</ButtonHelpStyledLeft>
</FlexSmall>
</FlexOuter>
)
}
Expand Down

0 comments on commit 3de1907

Please sign in to comment.