OverviewPage.tsx 14.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
import { translate } from 'react-i18next';
5
import * as _ from 'lodash';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
6
7

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

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

// UI
import PageLayout, { PageContents } from 'ui/layout/PageLayout';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
19
import GridContainer from 'ui/layout/GridContainer';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
20
import ContentHeader from 'ui/common/heading/ContentHeader';
21
import Loading from 'ui/common/Loading';
22
import Tabs, { Tab } from 'ui/common/Tabs';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
23
24
import PropertiesCard from 'ui/common/PropertiesCard';
import PrettyFilters from 'ui/common/filter/PrettyFilters';
25
import Number from 'ui/common/Number';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
26
import PageTitle from 'ui/common/PageTitle';
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
  apiCall: ApiCall<AccessionOverview>;
35
  suggestions: any;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
36
  filterCode: string;
37
  showSnackbar: (snack: string) => void;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
38
  applyOverviewFilters: (filters: string | AccessionFilter, page?: IPageRequest) => void;
39
  updateRouteWithFilterCode: (filterCode: string, path: string) => void;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
40
41
42
  currentTab: string;
  t: any;
}
43
/* tslint:disable */
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
44
45
46
class BrowsePage extends React.Component<IOverviewPageProps, any> {

  protected static needs = [
47
48
    ({ params: { filterCode } }) => {
      return applyOverviewFilters(filterCode || '');
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
49
50
51
52
53
54
55
56
    },
  ];

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

  public componentWillMount() {
57
58
59
    const {apiCall, filterCode, applyOverviewFilters, updateRouteWithFilterCode} = this.props;
    if (!apiCall) {
      return applyOverviewFilters(filterCode || '');
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
60
    }
61
62
63
64
65
66
67
68
69
70
71
    const {loading, data: overview} = apiCall;

    if (!loading && !overview) {
      return applyOverviewFilters(filterCode || '');
    }

    if (overview && filterCode && overview.filterCode !== filterCode) {
      return applyOverviewFilters(filterCode || '');
    }

    return updateRouteWithFilterCode(overview.filterCode, '/a/overview/');
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
72
  }
73

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
74
  public componentWillReceiveProps(nextProps) {
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
75
    const { filterCode: prevFilterCode } = this.props;
76
    const { filterCode, applyOverviewFilters, apiCall } = nextProps;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
77

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
78
    if (filterCode !== prevFilterCode) {
79
      if (apiCall && apiCall.data && !apiCall.loading && apiCall.data.filterCode !== filterCode) {
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
80
81
82
83
        applyOverviewFilters(filterCode || '');
      }
    }
  }
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
84

85

86
  private addTerm = (property, term) => {
87
88
89
      const { apiCall, applyOverviewFilters, showSnackbar } = this.props;
      const {data: overview} = apiCall || {data: undefined};

90
91
92

      const updatedFilter: AccessionFilter = { ...overview.filter };
      switch (property) {
Matija Obreza's avatar
Matija Obreza committed
93
        case 'crop':
94
        case 'sampStat':
95
96
97
98
99
        case 'institute.code':
        case 'institute.country.code3':
        case 'countryOfOrigin.code3':
        case 'taxonomy.genus':
        case 'taxonomy.species':
100
        case 'taxonomy.genusSpecies':
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
        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);
117
      showSnackbar('Applying filters...');
118
119
120
      applyOverviewFilters(updatedFilter);
  };

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
121
  public render() {
122
123
    const { filterCode, apiCall, currentTab, applyOverviewFilters, suggestions, t } = this.props;
    const {data: overviewWrapper, loading} = apiCall || {data: undefined, loading: true};
124
    const overview = overviewWrapper && overviewWrapper.overview || null;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
125

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

129
130
    const skipTerms = ['Other', 'Missing', 'Not specified'];

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
131
132
133
134
135
136
137
138
139
    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);
      });
    }

140
141
142
143
144
145
146
147
148
149
    const suggestionTerms = new Map();
    if (suggestions) {
      Object.keys(suggestions).forEach((key) => {
        const overviewEl = suggestions[key];
        const terms = new Map();
        overviewEl.terms.forEach((term) => terms.set(term.term, term.count));
        suggestionTerms.set(key, terms);
      });
    }

150
151
    const filterByTerm = (property, term, count) => {
        return (
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
152
153
154
            skipTerms.indexOf(term.term) === -1
                ? (<a onClick={ () => this.addTerm(property, term.term) }><Number value={ count } /></a>)
                : ( count )
155
156
157
        );
    };

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
158
159
160
    return (
      <PageLayout
        sidebar={
161
          <AccessionFilters terms={ suggestionTerms } initialValues={ overviewWrapper && overviewWrapper.filter || {} } onSubmit={ applyOverviewFilters }/>
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
162
        }
Oleksii Savran's avatar
Oleksii Savran committed
163
        withFooter
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
164
      >
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
165
        <PageTitle title={ t('accessions.public.p.browse.title') }/>
Matija Obreza's avatar
Matija Obreza committed
166
        <ContentHeader title={ t('accessions.public.p.browse.title') } subTitle={ t('accessions.public.p.browse.subTitle') } />
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
167
168
169
170
        <Tabs
          tab={ currentTab }
          actions={
            <span>
171
              <Button> Something </Button>
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
172
173
174
            </span>
          }
        >
Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
175
          <Tab name="overview" to={ `/a/overview/${filterCode || ''}` }>{ t('accessions.tab.overview') }</Tab>
Oleksii Savran's avatar
Oleksii Savran committed
176
          <Tab name="data" to={ `/a/${filterCode || ''}` }>{ t('accessions.tab.data') }</Tab>
Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
177
          <Tab name="map" to={ `/a/map/${filterCode || '' }` }>{ t('accessions.tab.map') }</Tab>
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
178
179
180
        </Tabs>
          <PrettyFilters
              prefix="accessions"
181
              filterObj={ overviewWrapper && overviewWrapper.filter || {} }
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
182
              onSubmit={ applyOverviewFilters }
Oleksii Savran's avatar
Oleksii Savran committed
183
184
              displayName="accessions.common.modelName"
              amount={ overviewWrapper && overviewWrapper.accessionCount }
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
185
          />
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
186
187
        { loading && <Loading /> }
        { overview &&
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
188
189
190
          <div>
            <PageContents className="pt-1rem">
              <GridContainer>
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
191
                { overviewsTerms && overviewsTerms.get('institute.code') && overviewsTerms.get('institute.code').length > 2 &&
192
                  <PropertiesCard propertiesList={ overviewsTerms.get('institute.code').map((term) => ({title: term.term, value: filterByTerm('institute.code', term, term.count) })) } title={ t(`accessions.common.overview.institute code`) } small propertyItemProps={ { numeric: true } } />
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
193
194
                }
                { overviewsTerms && overviewsTerms.get('institute.country.code3') && overviewsTerms.get('institute.country.code3').length > 2 &&
195
                  <PropertiesCard propertiesList={ overviewsTerms.get('institute.country.code3').map((term) => ({title: term.term, value: filterByTerm('institute.country.code3', term, term.count) })) } title={ t(`accessions.common.overview.institute country code3`) } small propertyItemProps={ { numeric: true } } />
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
196
197
                }
                { overviewsTerms && overviewsTerms.get('crop.shortName') && overviewsTerms.get('crop.shortName').length > 2 &&
Matija Obreza's avatar
Matija Obreza committed
198
                  <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
199
                }
200
                { overviewsTerms && overviewsTerms.get('cropName') && overviewsTerms.get('cropName').length > 2 &&
Matija Obreza's avatar
Matija Obreza committed
201
                  <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
202
203
                }
                { overviewsTerms && overviewsTerms.get('taxonomy.genus') && overviewsTerms.get('taxonomy.genus').length > 2 &&
204
                  <PropertiesCard propertiesList={ overviewsTerms.get('taxonomy.genus').map((term) => ({title: term.term, value: filterByTerm('taxonomy.genus', term, term.count) })) } title={ t(`accessions.common.overview.taxonomy genus`) } small propertyItemProps={ { numeric: true, classes: {propertiesRowLabel: 'font-italic'} } } />
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
205
206
                }
                { overviewsTerms && overviewsTerms.get('taxonomy.genusSpecies') && overviewsTerms.get('taxonomy.genusSpecies').length > 2 &&
207
                  <PropertiesCard propertiesList={ overviewsTerms.get('taxonomy.genusSpecies').map((term) => ({title: term.term, value: filterByTerm('taxonomy.genusSpecies', term, term.count) })) } title={ t(`accessions.common.overview.taxonomy genusSpecies`) } small propertyItemProps={ { numeric: true, classes: {propertiesRowLabel: 'font-italic'} } } />
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
208
                }
209
210
                { overviewsTerms && overviewsTerms.get('sampStat') && overviewsTerms.get('sampStat').length > 2 &&
                  <PropertiesCard propertiesList={ overviewsTerms.get('sampStat')
Matija Obreza's avatar
Matija Obreza committed
211
                    .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 } } />
212
213
                }
                { overviewsTerms && overviewsTerms.get('storage') && overviewsTerms.get('storage').length > 2 &&
Matija Obreza's avatar
Matija Obreza committed
214
                  <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 } } />
215
                }
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
216
                { overviewsTerms && overviewsTerms.get('countryOfOrigin.code3') && overviewsTerms.get('countryOfOrigin.code3').length > 2 &&
217
                  <PropertiesCard propertiesList={ overviewsTerms.get('countryOfOrigin.code3').map((term) => ({title: term.term, value: filterByTerm('countryOfOrigin.code3', term, term.count)})) } title={ t(`accessions.common.overview.countryOfOrigin code3`) } small propertyItemProps={ { numeric: true } } />
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
218
219
                }
                { overviewsTerms && overviewsTerms.get('donorCode') && overviewsTerms.get('donorCode').length > 2 &&
Matija Obreza's avatar
Matija Obreza committed
220
                  <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
221
                }
222
                { overviewsTerms && overviewsTerms.get('duplSite') && overviewsTerms.get('duplSite').length > 2 &&
Matija Obreza's avatar
Matija Obreza committed
223
                  <PropertiesCard propertiesList={ overviewsTerms.get('duplSite').map((term) => ({title: term.term, value: term.count })) } title={ t(`accessions.common.overview.duplSite`) } small propertyItemProps={ { numeric: true } } />
224
225
                }
                { overviewsTerms && overviewsTerms.get('breederCode') && overviewsTerms.get('breederCode').length > 2 &&
Matija Obreza's avatar
Matija Obreza committed
226
                  <PropertiesCard propertiesList={ overviewsTerms.get('breederCode').map((term) => ({title: term.term, value: term.count })) } title={ t(`accessions.common.overview.breederCode`) } small propertyItemProps={ { numeric: true } } />
227
                }
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
228
                { overviewsTerms && overviewsTerms.get('mlsStatus') && overviewsTerms.get('mlsStatus').length > 2 &&
Matija Obreza's avatar
Matija Obreza committed
229
                  <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
230
231
                }
                { overviewsTerms && overviewsTerms.get('available') && overviewsTerms.get('available').length > 2 &&
Matija Obreza's avatar
Matija Obreza committed
232
                  <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
233
                }
234
235
236
                { 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
237
                { overviewsTerms && overviewsTerms.get('sgsv') && overviewsTerms.get('sgsv').length > 2 &&
Matija Obreza's avatar
Matija Obreza committed
238
                  <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
239
                }
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
240
              </GridContainer>
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
241
242
243
244
245
246
247
248
249
            </PageContents>
          </div>
        }
      </PageLayout>
    );
  }
}

const mapStateToProps = (state, ownProps) => ({
250
  apiCall: state.accessions.public.overview,
251
  suggestions: state.accessions.public.suggestions,
Maxym Borodenko's avatar
Maxym Borodenko committed
252
  filterCode: ownProps.match.params.filterCode || '',
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
253
254
255
256
  currentTab: ownProps.match.params.tab || 'overview', // current tab, or ownProps.location.pathname
});

const mapDispatchToProps = (dispatch) => bindActionCreators({
257
  showSnackbar,
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
258
259
260
  applyFilters,
  applyOverviewFilters,
  loadAccessionsOverviewPage,
261
  updateRouteWithFilterCode,
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
262
263
264
265
}, dispatch);


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