OverviewPage.tsx 12.5 KB
Newer Older
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
1
import * as React from 'react';
2
3
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
4
5
import { parse } from 'query-string';
import { translate } from 'react-i18next';
6
import * as _ from 'lodash';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
7
8

// Actions
9
import { applyFilters, updateRoute, applyOverviewFilters, loadAccessionsOverviewPage } from 'accessions/actions/public';
10
import { showSnackbar } from 'actions/snackbar';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
11
12

// Models
13
import Accession from 'model/accession/Accession';
14
import FilteredPage, { IPageRequest } from 'model/FilteredPage';
15
16
import AccessionFilter from 'model/accession/AccessionFilter';
import AccessionOverview from 'model/accession/AccessionOverview';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
17
18
19

// UI
import PageLayout, { PageContents } from 'ui/layout/PageLayout';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
20
import GridContainer from 'ui/layout/GridContainer';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
21
import ContentHeader from 'ui/common/heading/ContentHeader';
22
import Loading from 'ui/common/Loading';
23
import Tabs, { Tab } from 'ui/common/Tabs';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
24
25
import PropertiesCard from 'ui/common/PropertiesCard';
import PrettyFilters from 'ui/common/filter/PrettyFilters';
26
import Number from 'ui/common/Number';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
27
28
29
30
31
32
33

import AccessionFilters from './c/Filters';

// TODO only for demo
import Button from '@material-ui/core/Button';

interface IOverviewPageProps extends React.ClassAttributes<any> {
34
  overview: AccessionOverview;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
35
36
  paged: FilteredPage<Accession>;
  filterCode: string;
37
  showSnackbar: (snack: string) => void;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
38
39
40
41
42
  applyOverviewFilters: (filters: string | AccessionFilter, page?: IPageRequest) => void;
  updateRoute: (paged: FilteredPage<Accession>, path?: string) => void;
  currentTab: string;
  t: any;
}
43
/* tslint:disable */
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
44
45
46
47
48
class BrowsePage extends React.Component<IOverviewPageProps, any> {

  protected static needs = [
    ({ search, params: { filterCode } }) => {
      const qs = parse(search || '');
49
      return applyOverviewFilters(filterCode || '', FilteredPage.fromQueryString(qs));
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
50
51
52
53
54
55
56
57
    },
  ];

  constructor(props: IOverviewPageProps, context: any) {
    super(props, context);
  }

  public componentWillMount() {
58
59
    const { overview, filterCode, applyOverviewFilters } = this.props;
    if (! overview || filterCode !== overview.filterCode) {
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
60
61
62
63
      applyOverviewFilters(filterCode || '');
    }
  }

64
  private addTerm = (property, term) => {
65
      const { overview, applyOverviewFilters, showSnackbar } = this.props;
66
67
68

      const updatedFilter: AccessionFilter = { ...overview.filter };
      switch (property) {
Matija Obreza's avatar
Matija Obreza committed
69
        case 'crop':
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
        case 'sampStat':
        case 'holder.code':
        case 'holder.country.iso3':
        case 'origin.iso3':
        case 'taxa.genus':
        case 'taxa.species':
        case 'storage':
          _.set(updatedFilter, property, _.concat(_.get(updatedFilter, property), term).filter(x => x != null));
          break;

        case 'sgsv':
        case 'available':
        case 'mlsStatus':
          _.set(updatedFilter, property, term === '1' ? true : false);
          break;

        // set
        default:
          _.set(updatedFilter, property, term);
      }

      // console.log(`Updated filter for ${property} +${term}`, updatedFilter);
92
      showSnackbar('Applying filters...');
93
94
95
      applyOverviewFilters(updatedFilter);
  };

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
96
  public render() {
97
98
    const { filterCode, currentTab, applyOverviewFilters, overview: overviewWrapper, t } = this.props;
    const overview = overviewWrapper && overviewWrapper.overview || null;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
99

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
100
    const overviewKeys = ['institute.code', 'institute.country.code3', 'cropName', 'crop.shortName', 'sampStat', 'taxonomy.genus', 'taxonomy.genusSpecies',
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
101
102
        'countryOfOrigin.code3', 'donorCode', 'mlsStatus', 'available', 'duplSite', 'sgsv', 'storage', 'breederCode'];

103
104
    const skipTerms = ['Other', 'Missing', 'Not specified'];

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
105
106
107
108
109
110
111
112
113
    const overviewsTerms = new Map();
    if (overview) {
      overviewKeys.forEach((key) => {
        const overviewEl = overview[key];
        const terms = [].concat(overviewEl.terms, {term: 'Other', count: overviewEl.other}, {term: 'Not specified', count: overviewEl.missing});
        overviewsTerms.set(key, terms);
      });
    }

114
115
    const filterByTerm = (property, term, count) => {
        return (
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
116
117
118
            skipTerms.indexOf(term.term) === -1
                ? (<a onClick={ () => this.addTerm(property, term.term) }><Number value={ count } /></a>)
                : ( count )
119
120
121
        );
    };

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
122
123
124
    return (
      <PageLayout
        sidebar={
125
          <AccessionFilters initialValues={ overviewWrapper && overviewWrapper.filter || {} } onSubmit={ applyOverviewFilters }/>
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
126
        }
Oleksii Savran's avatar
Oleksii Savran committed
127
        withFooter
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
128
      >
Matija Obreza's avatar
Matija Obreza committed
129
        <ContentHeader title={ t('accessions.public.p.browse.title') } subTitle={ t('accessions.public.p.browse.subTitle') } />
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
130
131
132
133
        <Tabs
          tab={ currentTab }
          actions={
            <span>
134
              <Button> Something </Button>
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
135
136
137
            </span>
          }
        >
Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
138
139
140
          <Tab name="data" to={ `/a/${filterCode || ''}` }>{ t('accessions.tab.data') }</Tab>
          <Tab name="overview" to={ `/a/overview/${filterCode || ''}` }>{ t('accessions.tab.overview') }</Tab>
          <Tab name="map" to={ `/a/map/${filterCode || '' }` }>{ t('accessions.tab.map') }</Tab>
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
141
142
143
        </Tabs>
          <PrettyFilters
              prefix="accessions"
144
              filterObj={ overviewWrapper && overviewWrapper.filter || {} }
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
145
146
              onSubmit={ applyOverviewFilters }
          />
147
        { ! overview ? <Loading /> :
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
148
149
150
          <div>
            <PageContents className="pt-1rem">
              <GridContainer>
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
151
                { overviewsTerms && overviewsTerms.get('institute.code') && overviewsTerms.get('institute.code').length > 2 &&
Matija Obreza's avatar
Matija Obreza committed
152
                  <PropertiesCard propertiesList={ overviewsTerms.get('institute.code').map((term) => ({title: term.term, value: filterByTerm('holder.code', term, term.count) })) } title={ t(`accessions.common.overview.institute code`) } small propertyItemProps={ { numeric: true } } />
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
153
154
                }
                { overviewsTerms && overviewsTerms.get('institute.country.code3') && overviewsTerms.get('institute.country.code3').length > 2 &&
Matija Obreza's avatar
Matija Obreza committed
155
                  <PropertiesCard propertiesList={ overviewsTerms.get('institute.country.code3').map((term) => ({title: term.term, value: filterByTerm('holder.country.iso3', term, term.count) })) } title={ t(`accessions.common.overview.institute country code3`) } small propertyItemProps={ { numeric: true } } />
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
156
157
                }
                { overviewsTerms && overviewsTerms.get('crop.shortName') && overviewsTerms.get('crop.shortName').length > 2 &&
Matija Obreza's avatar
Matija Obreza committed
158
                  <PropertiesCard propertiesList={ overviewsTerms.get('crop.shortName').map((term) => ({title: term.term, value: filterByTerm('crop', term, term.count)})) } title={ t(`accessions.common.overview.crop shortName`) } small propertyItemProps={ { numeric: true } } />
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
159
                }
160
                { overviewsTerms && overviewsTerms.get('cropName') && overviewsTerms.get('cropName').length > 2 &&
Matija Obreza's avatar
Matija Obreza committed
161
                  <PropertiesCard propertiesList={ overviewsTerms.get('cropName').map((term) => ({title: term.term, value: term.count })) } title={ t(`accessions.common.overview.cropName`) } small propertyItemProps={ { numeric: true } } />
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
162
163
                }
                { overviewsTerms && overviewsTerms.get('taxonomy.genus') && overviewsTerms.get('taxonomy.genus').length > 2 &&
Matija Obreza's avatar
Matija Obreza committed
164
                  <PropertiesCard propertiesList={ overviewsTerms.get('taxonomy.genus').map((term) => ({title: term.term, value: filterByTerm('taxa.genus', term, term.count) })) } title={ t(`accessions.common.overview.taxonomy genus`) } small propertyItemProps={ { numeric: true } } />
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
165
166
                }
                { overviewsTerms && overviewsTerms.get('taxonomy.genusSpecies') && overviewsTerms.get('taxonomy.genusSpecies').length > 2 &&
Matija Obreza's avatar
Matija Obreza committed
167
                  <PropertiesCard propertiesList={ overviewsTerms.get('taxonomy.genusSpecies').map((term) => ({title: term.term, value: term.count })) } title={ t(`accessions.common.overview.taxonomy genusSpecies`) } small propertyItemProps={ { numeric: true } } />
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
168
                }
169
170
                { overviewsTerms && overviewsTerms.get('sampStat') && overviewsTerms.get('sampStat').length > 2 &&
                  <PropertiesCard propertiesList={ overviewsTerms.get('sampStat')
Matija Obreza's avatar
Matija Obreza committed
171
                    .filter((term) => term.term !== 'other').map((term) => ({title: t([`accessions.common.sampleStatus.${term.term}`, `accessions.common.overview.${term.term}`]), value: filterByTerm('sampStat', term, term.count) })) } title={ t(`accessions.common.overview.sampStat`) } small propertyItemProps={ { numeric: true } } />
172
173
                }
                { overviewsTerms && overviewsTerms.get('storage') && overviewsTerms.get('storage').length > 2 &&
Matija Obreza's avatar
Matija Obreza committed
174
                  <PropertiesCard propertiesList={ overviewsTerms.get('storage').map((term) => ({title: t([`accessions.common.storage.${term.term}`, `accessions.common.overview.${term.term}`]), value: filterByTerm('storage', term, term.count) })) } title={ t(`accessions.common.overview.storage`) } small propertyItemProps={ { numeric: true } } />
175
                }
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
176
                { overviewsTerms && overviewsTerms.get('countryOfOrigin.code3') && overviewsTerms.get('countryOfOrigin.code3').length > 2 &&
Matija Obreza's avatar
Matija Obreza committed
177
                  <PropertiesCard propertiesList={ overviewsTerms.get('countryOfOrigin.code3').map((term) => ({title: term.term, value: filterByTerm('origin.iso3', term, term.count)})) } title={ t(`accessions.common.overview.countryOfOrigin code3`) } small propertyItemProps={ { numeric: true } } />
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
178
179
                }
                { overviewsTerms && overviewsTerms.get('donorCode') && overviewsTerms.get('donorCode').length > 2 &&
Matija Obreza's avatar
Matija Obreza committed
180
                  <PropertiesCard propertiesList={ overviewsTerms.get('donorCode').map((term) => ({title: term.term, value: term.count })) } title={ t(`accessions.common.overview.donorCode`) } small propertyItemProps={ { numeric: true } } />
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
181
                }
182
                { overviewsTerms && overviewsTerms.get('duplSite') && overviewsTerms.get('duplSite').length > 2 &&
Matija Obreza's avatar
Matija Obreza committed
183
                  <PropertiesCard propertiesList={ overviewsTerms.get('duplSite').map((term) => ({title: term.term, value: term.count })) } title={ t(`accessions.common.overview.duplSite`) } small propertyItemProps={ { numeric: true } } />
184
185
                }
                { overviewsTerms && overviewsTerms.get('breederCode') && overviewsTerms.get('breederCode').length > 2 &&
Matija Obreza's avatar
Matija Obreza committed
186
                  <PropertiesCard propertiesList={ overviewsTerms.get('breederCode').map((term) => ({title: term.term, value: term.count })) } title={ t(`accessions.common.overview.breederCode`) } small propertyItemProps={ { numeric: true } } />
187
                }
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
188
                { overviewsTerms && overviewsTerms.get('mlsStatus') && overviewsTerms.get('mlsStatus').length > 2 &&
Matija Obreza's avatar
Matija Obreza committed
189
                  <PropertiesCard propertiesList={ overviewsTerms.get('mlsStatus').map((term) => ({title: t([`accessions.common.mlsStatus.${term.term}`, `accessions.common.overview.${term.term}`]), value: filterByTerm('mlsStatus', term, term.count) })) } title={ t(`accessions.common.overview.mlsStatus`) } small propertyItemProps={ { numeric: true } } />
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
190
191
                }
                { overviewsTerms && overviewsTerms.get('available') && overviewsTerms.get('available').length > 2 &&
Matija Obreza's avatar
Matija Obreza committed
192
                  <PropertiesCard propertiesList={ overviewsTerms.get('available').map((term) => ({title: t([`accessions.common.available.${term.term}`, `accessions.common.overview.${term.term}`]), value: filterByTerm('available', term, term.count) })) } title={ t(`accessions.common.overview.available`) } small propertyItemProps={ { numeric: true } } />
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
193
194
                }
                { overviewsTerms && overviewsTerms.get('sgsv') && overviewsTerms.get('sgsv').length > 2 &&
Matija Obreza's avatar
Matija Obreza committed
195
                  <PropertiesCard propertiesList={ overviewsTerms.get('sgsv').map((term) => ({title: t([`accessions.common.sgsv.${term.term}`, `accessions.common.overview.${term.term}`]), value: filterByTerm('sgsv', term, term.count) })) } title={ t(`accessions.common.overview.sgsv`) } small propertyItemProps={ { numeric: true } } />
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
196
                }
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
197
              </GridContainer>
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
198
199
200
201
202
203
204
205
206
            </PageContents>
          </div>
        }
      </PageLayout>
    );
  }
}

const mapStateToProps = (state, ownProps) => ({
207
208
  paged: state.accessions.public.paged || undefined,
  overview: state.accessions.public.overview,
Maxym Borodenko's avatar
Maxym Borodenko committed
209
  filterCode: ownProps.match.params.filterCode || '',
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
210
211
212
213
  currentTab: ownProps.match.params.tab || 'overview', // current tab, or ownProps.location.pathname
});

const mapDispatchToProps = (dispatch) => bindActionCreators({
214
  showSnackbar,
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
215
216
217
218
219
220
221
222
  applyFilters,
  applyOverviewFilters,
  loadAccessionsOverviewPage,
  updateRoute,
}, dispatch);


export default connect(mapStateToProps, mapDispatchToProps)(translate()(BrowsePage));