From 2adbd9256fa0c5feae5c092a0aafa9ffcee0fa59 Mon Sep 17 00:00:00 2001 From: ivan-aksamentov Date: Tue, 1 Dec 2020 16:29:42 +0100 Subject: [PATCH] feat: customize instruction and placeholder text on url and paste comps. --- .../web/src/components/Main/FilePicker.tsx | 21 ++++++++++++++----- .../components/Main/FilePickerAdvanced.tsx | 18 +++++++++++++--- .../Main/MainSectionHeroControlsSimple.tsx | 2 ++ .../web/src/components/Main/TabPanelPaste.tsx | 10 ++++----- .../web/src/components/Main/TabPanelUrl.tsx | 9 +++++--- .../src/components/Main/UploaderFileIcons.tsx | 10 ++++----- 6 files changed, 49 insertions(+), 21 deletions(-) diff --git a/packages/web/src/components/Main/FilePicker.tsx b/packages/web/src/components/Main/FilePicker.tsx index eb83d7e8c..f62a5e20c 100644 --- a/packages/web/src/components/Main/FilePicker.tsx +++ b/packages/web/src/components/Main/FilePicker.tsx @@ -1,4 +1,4 @@ -import React, { ReactNode, Ref, useState } from 'react' +import React, { ReactNode, Ref, useMemo, useState } from 'react' import styled from 'styled-components' import { @@ -185,6 +185,8 @@ export const NonCollapsibleIcon = styled(FaAsterisk)` export interface FilePickerProps { icon: ReactNode text: ReactNode + exampleUrl: string + pasteInstructions: string input?: AlgorithmInput errors: Error[] inputRef?: Ref @@ -201,6 +203,8 @@ export interface FilePickerProps { export function FilePicker({ icon, text, + exampleUrl, + pasteInstructions, input, errors, onInput, @@ -242,6 +246,13 @@ export function FilePicker({ onRemove([]) } + const collapseToggleIconTooltip = useMemo( + () => (shouldCollapse ? t('Expand this section') : t('Collapse this section')), + [shouldCollapse, t], + ) + + const badge = useMemo(() => (canCollapse ? : ), [canCollapse]) + if (input) { return ( @@ -262,7 +273,7 @@ export function FilePicker({

{canCollapse ? ( - {canCollapse ? : } + {badge} @@ -310,11 +321,11 @@ export function FilePicker({ - + - + diff --git a/packages/web/src/components/Main/FilePickerAdvanced.tsx b/packages/web/src/components/Main/FilePickerAdvanced.tsx index 736a10398..6e73edcac 100644 --- a/packages/web/src/components/Main/FilePickerAdvanced.tsx +++ b/packages/web/src/components/Main/FilePickerAdvanced.tsx @@ -4,7 +4,7 @@ import { connect } from 'react-redux' import { useTranslation } from 'react-i18next' import { Col, Row } from 'reactstrap' import { FilePicker } from 'src/components/Main/FilePicker' -import { FileIconFasta, FileIconJson, FileIconTxt } from 'src/components/Main/UploaderFileIcons' +import { FileIconFasta, FileIconJson, FileIconCsv } from 'src/components/Main/UploaderFileIcons' import { algorithmRunAsync, removeFasta, @@ -118,6 +118,8 @@ export function FilePickerAdvancedDisconnected({ } text={t('Sequences')} + exampleUrl="https://example.com/sequences.fasta" + pasteInstructions={t('Enter sequence data in FASTA or plain text format')} canCollapse={false} defaultCollapsed={false} input={params.raw.seqData} @@ -129,6 +131,8 @@ export function FilePickerAdvancedDisconnected({ } text={t('Reference tree')} + exampleUrl="https://example.com/tree.json" + pasteInstructions={t('Enter tree data in Auspice JSON v2 format')} input={params.raw.auspiceData} errors={params.errors.auspiceData} onRemove={removeTree} @@ -136,8 +140,10 @@ export function FilePickerAdvancedDisconnected({ /> } + icon={} text={t('Root sequence')} + exampleUrl="https://example.com/root_seq.fasta" + pasteInstructions={t('Enter tree data in FASTA or plain text format')} input={params.raw.rootSeq} errors={params.errors.rootSeq} onRemove={removeRootSeq} @@ -147,6 +153,8 @@ export function FilePickerAdvancedDisconnected({ } text={t('Quality control')} + exampleUrl="https://example.com/qc.json" + pasteInstructions={t('Enter QC config in JSON format')} input={params.raw.qcRulesConfig} errors={params.errors.qcRulesConfig} onRemove={removeQcSettings} @@ -156,6 +164,8 @@ export function FilePickerAdvancedDisconnected({ } text={t('Gene map')} + exampleUrl="https://example.com/gene_map.json" + pasteInstructions={t('Enter gene map data in JSON format')} input={params.raw.geneMap} errors={params.errors.geneMap} onRemove={removeGeneMap} @@ -163,8 +173,10 @@ export function FilePickerAdvancedDisconnected({ /> } + icon={} text={t('PCR primers')} + exampleUrl="https://example.com/pcr_primers.csv" + pasteInstructions={t('Enter PCR primers data in CSV format')} input={params.raw.pcrPrimers} errors={params.errors.pcrPrimers} onRemove={removePcrPrimers} diff --git a/packages/web/src/components/Main/MainSectionHeroControlsSimple.tsx b/packages/web/src/components/Main/MainSectionHeroControlsSimple.tsx index f6ee36a19..279dd8737 100644 --- a/packages/web/src/components/Main/MainSectionHeroControlsSimple.tsx +++ b/packages/web/src/components/Main/MainSectionHeroControlsSimple.tsx @@ -99,6 +99,8 @@ export function MainSectionHeroControlsDisconnected({ defaultCollapsed={false} icon={} text={t('Sequences')} + exampleUrl="https://example.com/sequences.fasta" + pasteInstructions={t('Enter sequence data in FASTA or plain text format')} input={params.raw.seqData} onInput={onUpload} errors={params.errors.seqData} diff --git a/packages/web/src/components/Main/TabPanelPaste.tsx b/packages/web/src/components/Main/TabPanelPaste.tsx index a0703ca57..7a96c0e48 100644 --- a/packages/web/src/components/Main/TabPanelPaste.tsx +++ b/packages/web/src/components/Main/TabPanelPaste.tsx @@ -17,12 +17,14 @@ import { import { useTranslationSafe } from 'src/helpers/useTranslationSafe' export interface TabPanelPasteProps { + pasteInstructions: string + inputRef?: Ref onConfirm(seqData: string): void } -export function TabPanelPaste({ onConfirm, inputRef }: TabPanelPasteProps) { +export function TabPanelPaste({ onConfirm, pasteInstructions, inputRef }: TabPanelPasteProps) { const { t } = useTranslationSafe() const [seqData, setSeqData] = useState('') const hasSeqData = seqData.length > 0 @@ -37,7 +39,7 @@ export function TabPanelPaste({ onConfirm, inputRef }: TabPanelPasteProps) { @@ -79,9 +81,7 @@ export function TabPanelPaste({ onConfirm, inputRef }: TabPanelPasteProps) { disabled={!hasSeqData} type="button" color="primary" - title={ - hasSeqData ? 'Accept sequence data' : 'Please provide sequence data before the analysis is possible' - } + title={hasSeqData ? t('Accept the data') : t('Please provide the data first')} onClick={confirm} > {t('OK')} diff --git a/packages/web/src/components/Main/TabPanelUrl.tsx b/packages/web/src/components/Main/TabPanelUrl.tsx index ca454de76..c5f17b91d 100644 --- a/packages/web/src/components/Main/TabPanelUrl.tsx +++ b/packages/web/src/components/Main/TabPanelUrl.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react' +import React, { useMemo, useState } from 'react' import { Col } from 'reactstrap' // eslint-disable-next-line import/no-cycle @@ -18,16 +18,19 @@ import { import { useTranslationSafe } from 'src/helpers/useTranslationSafe' export interface TabPanelUrlProps { + exampleUrl: string + onConfirm(url: string): void } -export function TabPanelUrl({ onConfirm }: TabPanelUrlProps) { +export function TabPanelUrl({ exampleUrl, onConfirm }: TabPanelUrlProps) { const { t } = useTranslationSafe() const [url, setUrl] = useState('') const hasUrl = url.length > 0 const change = (e: React.ChangeEvent) => setUrl(e.target.value) const clear = () => setUrl('') const confirm = () => onConfirm(url) + const placeholder = useMemo(() => t('For example: {{exampleUrl}}', { exampleUrl }), [t, exampleUrl]) return (
@@ -48,7 +51,7 @@ export function TabPanelUrl({ onConfirm }: TabPanelUrlProps) { id="tree-url-text-input" className="flex-grow-1" type="textarea" - placeholder={t('For example: {{exampleUrl}}', { exampleUrl: 'https://example.com/data.fasta' })} + placeholder={placeholder} autoComplete="off" autoCorrect="off" autoCapitalize="off" diff --git a/packages/web/src/components/Main/UploaderFileIcons.tsx b/packages/web/src/components/Main/UploaderFileIcons.tsx index b8d06b88b..006c158e8 100644 --- a/packages/web/src/components/Main/UploaderFileIcons.tsx +++ b/packages/web/src/components/Main/UploaderFileIcons.tsx @@ -15,7 +15,7 @@ export const DEFAULT_ICON_SIZE = 50 as const export const DEFAULT_ICON_COLORS = { fasta: '#66b51d', - txt: '#777777', + csv: '#777777', json: '#bb7e38', } as const @@ -98,11 +98,11 @@ export const FileIconJson = ({ size }: FileIconProps) => ( /> ) -export const FileIconTxt = ({ size }: FileIconProps) => ( +export const FileIconCsv = ({ size }: FileIconProps) => ( )