OverviewPage.tsx 13.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
import PageTitle from 'ui/common/PageTitle';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
28
29
30
31
32
33
34

import AccessionFilters from './c/Filters';

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

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

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

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

  public componentWillMount() {
59
60
    const { overview, filterCode, applyOverviewFilters } = this.props;
    if (! overview || filterCode !== overview.filterCode) {
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
61
62
63
      applyOverviewFilters(filterCode || '');
    }
  }
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
64
65
66
67
68
69
70
71
72
73
  public componentWillReceiveProps(nextProps) {
    const { filterCode: prevCode, overview: prevOverview } = this.props;
    const { filterCode, applyOverviewFilters, overview } = nextProps;

    if (prevOverview && overview && _.isEqual(overview.filter, prevOverview.filter)) {
      if (prevCode !== filterCode) {
        applyOverviewFilters(filterCode || '');
      }
    }
  }
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
74

75
  private addTerm = (property, term) => {
76
      const { overview, applyOverviewFilters, showSnackbar } = this.props;
77
78
79

      const updatedFilter: AccessionFilter = { ...overview.filter };
      switch (property) {
Matija Obreza's avatar
Matija Obreza committed
80
        case 'crop':
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
        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);
103
      showSnackbar('Applying filters...');
104
105
106
      applyOverviewFilters(updatedFilter);
  };

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
107
  public render() {
108
109
    const { filterCode, currentTab, applyOverviewFilters, overview: overviewWrapper, t } = this.props;
    const overview = overviewWrapper && overviewWrapper.overview || null;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
110

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

114
115
    const skipTerms = ['Other', 'Missing', 'Not specified'];

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
116
117
118
119
120
121
122
123
124
    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);
      });
    }

125
126
    const filterByTerm = (property, term, count) => {
        return (
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
127
128
129
            skipTerms.indexOf(term.term) === -1
                ? (<a onClick={ () => this.addTerm(property, term.term) }><Number value={ count } /></a>)
                : ( count )
130
131
132
        );
    };

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

const mapStateToProps = (state, ownProps) => ({
222
223
  paged: state.accessions.public.paged || undefined,
  overview: state.accessions.public.overview,
Maxym Borodenko's avatar
Maxym Borodenko committed
224
  filterCode: ownProps.match.params.filterCode || '',
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
225
226
227
228
  currentTab: ownProps.match.params.tab || 'overview', // current tab, or ownProps.location.pathname
});

const mapDispatchToProps = (dispatch) => bindActionCreators({
229
  showSnackbar,
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
230
231
232
233
234
235
236
237
  applyFilters,
  applyOverviewFilters,
  loadAccessionsOverviewPage,
  updateRoute,
}, dispatch);


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