DefaultTranscriptListItem.tsx 4.62 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/**
 * 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.
 */

17
import React from 'react';
18
import { connect } from 'react-redux';
19 20 21 22

import { getFeatureCoordinates } from 'src/content/app/entity-viewer/shared/helpers/entity-helpers';

import UnsplicedTranscript from 'src/content/app/entity-viewer/gene-view/components/unspliced-transcript/UnsplicedTranscript';
23
import TranscriptsListItemInfo from '../transcripts-list-item-info/TranscriptsListItemInfo';
24

25
import { toggleTranscriptInfo } from 'src/content/app/entity-viewer/state/gene-view/transcripts/geneViewTranscriptsSlice';
26

27 28 29
import { Gene } from 'src/content/app/entity-viewer/types/gene';
import { Transcript } from 'src/content/app/entity-viewer/types/transcript';
import { TicksAndScale } from 'src/content/app/entity-viewer/gene-view/components/base-pairs-ruler/BasePairsRuler';
30
import QuestionButton from 'src/shared/components/question-button/QuestionButton';
31

32
import transcriptsListStyles from '../DefaultTranscriptsList.scss';
33 34
import styles from './DefaultTranscriptListItem.scss';

35 36 37 38 39
type defaultTranscriptLabelType = {
  label: string;
  helpText: string;
};

40
export type DefaultTranscriptListItemProps = {
41
  gene: Gene;
42 43
  isDefault?: boolean;
  defaultTranscriptLabel?: defaultTranscriptLabelType;
44 45
  transcript: Transcript;
  rulerTicks: TicksAndScale;
46 47 48
  expandTranscript: boolean;
  expandDownload: boolean;
  toggleTranscriptInfo: (id: string) => void;
49 50 51 52
};

// NOTE: the width of the middle column is the same as the width of GeneOverviewImage, i.e. 695px

53 54 55
export const DefaultTranscriptListItem = (
  props: DefaultTranscriptListItemProps
) => {
56 57 58 59 60 61 62
  const { scale } = props.rulerTicks;
  const { start: geneStart } = getFeatureCoordinates(props.gene);
  const { start: transcriptStart, end: transcriptEnd } = getFeatureCoordinates(
    props.transcript
  );
  const transcriptStartX = scale(transcriptStart - geneStart); // FIXME In future, this should be done using relative position of transcript in gene
  const transcriptWidth = scale(transcriptEnd - transcriptStart); // FIXME  this too should be based on relative coordinates of transcript
63

64 65 66 67 68 69 70 71 72 73
  const defaultTranscriptLabelMap = {
    selected: {
      label: 'Selected',
      helpText:
        'The selected transcript is a default single transcript per protein coding gene that is representative of biology, well-supported, expressed and highly conserved'
    }
  };

  const canonicalType = 'selected'; // TODO Change this to transcript.mane/plus etc when available

74
  return (
75 76
    <div className={styles.defaultTranscriptListItem}>
      <div className={transcriptsListStyles.row}>
77 78
        {props.isDefault && (
          <div className={styles.defaultTranscriptLabel}>
79
            <span>{defaultTranscriptLabelMap[canonicalType]?.label}</span>
80 81 82 83 84
            <QuestionButton
              helpText={defaultTranscriptLabelMap[canonicalType]?.helpText}
            />
          </div>
        )}
Andrey Azov's avatar
Andrey Azov committed
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
        <div className={transcriptsListStyles.middle}>
          <div
            className={styles.clickableTranscriptArea}
            onClick={() => props.toggleTranscriptInfo(props.transcript.id)}
          >
            <div
              className={styles.transcriptWrapper}
              style={{ transform: `translateX(${transcriptStartX}px)` }}
            >
              <UnsplicedTranscript
                transcript={props.transcript}
                width={transcriptWidth}
                standalone={true}
              />
            </div>
100 101 102 103
          </div>
        </div>
        <div
          className={transcriptsListStyles.right}
104
          onClick={() => props.toggleTranscriptInfo(props.transcript.id)}
105 106
        >
          <span className={styles.transcriptId}>{props.transcript.id}</span>
107 108
        </div>
      </div>
109
      {props.expandTranscript ? (
110 111 112
        <TranscriptsListItemInfo
          gene={props.gene}
          transcript={props.transcript}
113
          expandDownload={props.expandDownload}
114
        />
115
      ) : null}
116 117 118 119
    </div>
  );
};

120 121 122 123 124
const mapDispatchToProps = {
  toggleTranscriptInfo
};

export default connect(null, mapDispatchToProps)(DefaultTranscriptListItem);