/** * See the NOTICE file distributed with this work for additional information * regarding copyright ownership. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import React, { useState, useEffect } from 'react'; import classNames from 'classnames'; import pick from 'lodash/pick'; import intersection from 'lodash/intersection'; import { fetchForTranscript } from '../instant-download-fetch/fetchForTranscript'; import InstantDownloadTranscriptVisualisation from './InstantDownloadTranscriptVisualisation'; import Checkbox from 'src/shared/components/checkbox/Checkbox'; import InstantDownloadButton from '../instant-download-button/InstantDownloadButton'; import styles from './InstantDownloadTranscript.scss'; type Layout = 'horizontal' | 'vertical'; type Theme = 'light' | 'dark'; type TranscriptFields = { id: string; biotype: string; }; type GeneFields = { id: string; }; export type InstantDownloadTranscriptEntityProps = { genomeId: string; transcript: TranscriptFields; gene: GeneFields; }; type Props = InstantDownloadTranscriptEntityProps & { layout: Layout; theme: Theme; }; type TranscriptSectionProps = { transcript: TranscriptFields; options: Partial; theme: Theme; onChange: (key: keyof TranscriptOptions) => void; }; type GeneSectionProps = { gene: GeneFields; isGenomicSequenceSelected: boolean; onChange: () => void; }; export type TranscriptOptions = { genomicSequence: boolean; proteinSequence: boolean; cdna: boolean; cds: boolean; }; export type TranscriptOption = keyof Partial; export const transcriptOptionsOrder: TranscriptOption[] = [ 'genomicSequence', 'cdna', 'proteinSequence', 'cds' ]; export const defaultTranscriptOptions: TranscriptOptions = { genomicSequence: false, cdna: false, proteinSequence: false, cds: false }; const transcriptOptionLabels: Record = { genomicSequence: 'Genomic sequence', proteinSequence: 'Protein sequence', cdna: 'cDNA', cds: 'CDS' }; export const filterTranscriptOptions = ( biotype: string ): Partial => { return biotype === 'protein_coding' ? defaultTranscriptOptions : pick(defaultTranscriptOptions, ['genomicSequence', 'cdna']); }; const InstantDownloadTranscript = (props: Props) => { const { genomeId, gene: { id: geneId }, transcript: { id: transcriptId, biotype } } = props; const [transcriptOptions, setTranscriptOptions] = useState( filterTranscriptOptions(biotype) ); const [isGeneSequenceSelected, setIsGeneSequenceSelected] = useState(false); useEffect(() => { setTranscriptOptions(filterTranscriptOptions(biotype)); }, [biotype]); const resetCheckboxes = () => { setIsGeneSequenceSelected(false); setTranscriptOptions(filterTranscriptOptions(biotype)); }; const onSubmit = async () => { const payload = { genomeId, geneId, transcriptId, options: { transcript: transcriptOptions, gene: { genomicSequence: isGeneSequenceSelected } } }; try { await fetchForTranscript(payload); } finally { resetCheckboxes(); } }; const onTranscriptOptionChange = (key: keyof TranscriptOptions) => { const updatedOptions = { ...transcriptOptions, [key]: !transcriptOptions[key] }; setTranscriptOptions(updatedOptions); }; const onGeneOptionChange = () => { setIsGeneSequenceSelected(!isGeneSequenceSelected); }; const layoutClass = props.layout === 'horizontal' ? classNames(styles.layout, styles.layoutHorizontal) : classNames(styles.layout, styles.layoutVertical); const themeClass = props.theme === 'dark' ? styles.themeDark : styles.themeLight; const wrapperClassNames = classNames(themeClass, layoutClass); const isButtonDisabled = !hasSelectedOptions({ ...transcriptOptions, geneSequence: isGeneSequenceSelected }); return (
); }; InstantDownloadTranscript.defaultProps = { layout: 'horizontal', theme: 'dark' } as Props; const TranscriptSection = (props: TranscriptSectionProps) => { const { transcript, options } = props; const orderedOptionKeys = intersection( transcriptOptionsOrder, Object.keys(options) ); const checkboxes = orderedOptionKeys.map((key) => ( props.onChange(key as TranscriptOption)} /> )); const transcriptVisualisation = ( ); return (
Transcript {transcript.id}
{transcriptVisualisation}
{checkboxes}
); }; const GeneSection = (props: GeneSectionProps) => { return (
Gene {props.gene.id}
); }; const hasSelectedOptions = ( options: Partial & { geneSequence: boolean } ) => { return Object.keys(options).some( (key) => options[key as keyof TranscriptOptions] ); }; export default InstantDownloadTranscript;