TrackPanelBookmarks.tsx 6.03 KB
Newer Older
Andrey Azov's avatar
Andrey Azov committed
1
import React from 'react';
Imran Salam's avatar
Imran Salam committed
2
import { Link } from 'react-router-dom';
3
import { connect } from 'react-redux';
4
import upperFirst from 'lodash/upperFirst';
5
6

import { RootState } from 'src/store';
7
import { EnsObject } from 'src/shared/state/ens-object/ensObjectTypes';
8
import { getBrowserActiveGenomeId } from '../../../browserSelectors';
9
10
11
import { updateTrackStatesAndSave } from 'src/content/app/browser/browserActions';
import { BrowserTrackStates } from 'src/content/app/browser/track-panel/trackPanelConfig';
import { getActiveGenomePreviouslyViewedObjects } from 'src/content/app/browser/track-panel/trackPanelSelectors';
12
13
import { fetchExampleEnsObjects } from 'src/shared/state/ens-object/ensObjectActions';
import { getExampleEnsObjects } from 'src/shared/state/ens-object/ensObjectSelectors';
14
import * as urlFor from 'src/shared/helpers/urlHelper';
15
16
17
18
19
import { closeTrackPanelModal } from '../../trackPanelActions';
import ImageButton from 'src/shared/components/image-button/ImageButton';
import { ReactComponent as EllipsisIcon } from 'static/img/track-panel/ellipsis.svg';
import { changeDrawerViewAndOpen } from 'src/content/app/browser/drawer/drawerActions';
import { PreviouslyViewedObject } from 'src/content/app/browser/track-panel/trackPanelState';
20
import analyticsTracking from 'src/services/analytics-service';
21

22
import { Status } from 'src/shared/types/status';
Imran Salam's avatar
Imran Salam committed
23

24
25
import styles from './TrackPanelBookmarks.scss';

26
export type TrackPanelBookmarksProps = {
Andrey Azov's avatar
Andrey Azov committed
27
28
  activeGenomeId: string | null;
  exampleEnsObjects: EnsObject[];
29
  previouslyViewedObjects: PreviouslyViewedObject[];
30
  fetchExampleEnsObjects: (objectId: string) => void;
31
32
33
  updateTrackStatesAndSave: (trackStates: BrowserTrackStates) => void;
  closeTrackPanelModal: () => void;
  changeDrawerViewAndOpen: (drawerView: string) => void;
34
35
};

36
37
38
39
40
41
42
43
44
45
46
47
type ExampleLinksProps = Pick<
  TrackPanelBookmarksProps,
  'exampleEnsObjects' | 'activeGenomeId' | 'closeTrackPanelModal'
>;
export const ExampleLinks = (props: ExampleLinksProps) => {
  return (
    <div>
      {props.exampleEnsObjects.map((exampleObject) => {
        const path = urlFor.browser({
          genomeId: props.activeGenomeId,
          focus: exampleObject.object_id
        });
48

49
50
51
52
53
54
55
56
57
58
59
60
61
62
        return (
          <div key={exampleObject.object_id} className={styles.linkHolder}>
            <Link to={path} onClick={props.closeTrackPanelModal}>
              {exampleObject.label}
            </Link>
            <span className={styles.previouslyViewedType}>
              {upperFirst(exampleObject.object_type)}
            </span>
          </div>
        );
      })}
    </div>
  );
};
Andrey Azov's avatar
Andrey Azov committed
63

64
65
66
67
68
69
70
71
type PreviouslyViewedLinksProps = Pick<
  TrackPanelBookmarksProps,
  | 'previouslyViewedObjects'
  | 'updateTrackStatesAndSave'
  | 'closeTrackPanelModal'
>;

export const PreviouslyViewedLinks = (props: PreviouslyViewedLinksProps) => {
72
73
74
75
76
77
78
79
80
81
82
  const onLinkClick = (objectType: string, index: number) => {
    analyticsTracking.trackEvent({
      category: 'recent_bookmark_link',
      label: objectType,
      action: 'clicked',
      value: index + 1
    });

    props.closeTrackPanelModal();
  };

83
84
85
86
87
88
89
90
91
92
93
94
  return (
    <div>
      {[...props.previouslyViewedObjects]
        .reverse()
        .map((previouslyViewedObject, index) => {
          const path = urlFor.browser({
            genomeId: previouslyViewedObject.genome_id,
            focus: previouslyViewedObject.object_id
          });

          return (
            <div key={index} className={styles.linkHolder}>
95
96
97
98
99
100
              <Link
                to={path}
                onClick={() =>
                  onLinkClick(previouslyViewedObject.object_type, index)
                }
              >
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
                {previouslyViewedObject.label}
              </Link>
              <span className={styles.previouslyViewedType}>
                {upperFirst(previouslyViewedObject.object_type)}
              </span>
            </div>
          );
        })}
    </div>
  );
};

export const TrackPanelBookmarks = (props: TrackPanelBookmarksProps) => {
  const {
    previouslyViewedObjects,
    exampleEnsObjects,
    activeGenomeId,
    updateTrackStatesAndSave,
    closeTrackPanelModal
  } = props;

  const limitedPreviouslyViewedObjects = previouslyViewedObjects.slice(-20);
123

124
125
126
127
128
129
130
131
132
133
134
  const onEllipsisClick = () => {
    analyticsTracking.trackEvent({
      category: 'drawer_open',
      label: 'recent_bookmarks',
      action: 'clicked',
      value: previouslyViewedObjects.length
    });

    props.changeDrawerViewAndOpen('bookmarks');
  };

Imran Salam's avatar
Imran Salam committed
135
136
137
  return (
    <section className="trackPanelBookmarks">
      <h3>Bookmarks</h3>
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
      {exampleEnsObjects.length ? (
        <>
          <div className={styles.title}>Example links</div>
          <ExampleLinks
            exampleEnsObjects={exampleEnsObjects}
            activeGenomeId={activeGenomeId}
            closeTrackPanelModal={closeTrackPanelModal}
          />
        </>
      ) : null}
      {limitedPreviouslyViewedObjects.length ? (
        <>
          <div className={styles.title}>
            Previously viewed
            {props.previouslyViewedObjects.length > 20 && (
              <span className={styles.ellipsis}>
                <ImageButton
                  buttonStatus={Status.ACTIVE}
                  description={'View all'}
                  image={EllipsisIcon}
158
                  onClick={onEllipsisClick}
159
160
161
162
163
164
165
166
167
168
                />
              </span>
            )}
          </div>
          <PreviouslyViewedLinks
            previouslyViewedObjects={limitedPreviouslyViewedObjects}
            updateTrackStatesAndSave={updateTrackStatesAndSave}
            closeTrackPanelModal={closeTrackPanelModal}
          />
        </>
169
      ) : null}
Imran Salam's avatar
Imran Salam committed
170
171
172
173
    </section>
  );
};

174
const mapStateToProps = (state: RootState) => ({
175
  activeGenomeId: getBrowserActiveGenomeId(state),
176
177
  exampleEnsObjects: getExampleEnsObjects(state),
  previouslyViewedObjects: getActiveGenomePreviouslyViewedObjects(state)
178
179
180
});

const mapDispatchToProps = {
181
182
183
184
  fetchExampleEnsObjects,
  updateTrackStatesAndSave,
  closeTrackPanelModal,
  changeDrawerViewAndOpen
185
186
187
188
189
190
};

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(TrackPanelBookmarks);