DisplayPage.tsx 14.2 KB
Newer Older
1
2
3
import * as React from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
Matija Obreza's avatar
Matija Obreza committed
4
import { translate } from 'react-i18next';
5
6

// Actions
7
import { loadAccession } from 'accessions/actions/public';
8
import {addAccessionToMyList, removeAccessionFromMyList} from 'list/actions/public';
9
10

// Models
11
import AccessionDetails from 'model/accession/AccessionDetails';
12
13

// UI
Matija Obreza's avatar
Matija Obreza committed
14
15
16
import { Link } from 'react-router-dom';
import PrettyDate from 'ui/common/time/PrettyDate';
import PageLayout, { PageContents, MainSection, PageSection } from 'ui/layout/PageLayout';
17
18
import ContentHeader from 'ui/common/heading/ContentHeader';
import Loading from 'ui/common/Loading';
Matija Obreza's avatar
Matija Obreza committed
19
20
21
22
23
import { Properties, PropertiesItem } from 'ui/common/Properties';
import DOI from 'ui/common/DOI';
import { ExternalLink } from 'ui/common/Links';
import SciName from 'ui/genesys/SciName';
import { ScrollToTopOnMount } from 'ui/common/page/scrollers';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
24
import ReduxCheckbox from 'ui/common/checkbox';
25
import CropChips from 'crop/ui/c/CropChips';
26
import LocationMap from 'ui/common/LocationMap';
27
28
29
import {CountryLink, DatasetLink, InstituteLink, SubsetLink} from 'ui/genesys/Links';
import PropertiesCard from 'ui/common/PropertiesCard';
import GridLayout from 'ui/layout/GridLayout';
30
import McpdDate from 'ui/common/time/McpdDate';
31
import PdciTable from './c/PdciTable';
Matija Obreza's avatar
Matija Obreza committed
32

33
34

interface IBrowsePageProps extends React.ClassAttributes<any> {
Matija Obreza's avatar
Matija Obreza committed
35
  t: any;
36
  uuid: string;
37
  doi: string; // DOI comes from the route without the '10.'
38
  accession: AccessionDetails;
39
40
  error: any;
  loadAccession: any;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
41
42
43
  accessions: any;
  addAccessionToMyList: any;
  removeAccessionFromMyList: any;
44
45
46
47
48
}

class BrowsePage extends React.Component<IBrowsePageProps, any> {

  protected static needs = [
49
    ({ params: { uuid, doi } }) => {
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
50
        return doi ? loadAccession({ doi: `10.${doi}` }) :  loadAccession({ uuid });
51
52
53
54
55
56
57
58
    },
  ];

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

  public componentWillMount() {
59
60
61
    const { doi, uuid, loadAccession } = this.props;
    const accession = this.props.accession ? this.props.accession.details : null;

62
63
64
65
    const theDoi = `10.${doi}`;
    if (doi && (! accession || theDoi !== accession.doi)) {
      loadAccession({ doi: theDoi });
    }
66
    if (uuid && (! accession || uuid !== accession.uuid)) {
67
      loadAccession({ uuid });
68
69
70
    }
  }

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
71
  private onCheckboxChange = (event, checked) => {
72
      const {accession: {details: accession}, addAccessionToMyList, removeAccessionFromMyList} = this.props;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
73
74
75
76
77
78
79
      if (checked) {
          addAccessionToMyList(accession.uuid);
      } else {
          removeAccessionFromMyList(accession.uuid);
        }
  }

80
  public render() {
81
82
83
84
85
86
    const { t, error, uuid, doi, accessions } = this.props;
    const {details: accession, pdci, datasets, subsets} = this.props.accession ?
      this.props.accession
      :
      {details: null, pdci: null, datasets: null, subsets: null};

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
87
    const  isChecked  =  accession && accessions && accessions.includes(accession.uuid);
88
89
90
91
    const theDoi = `10.${doi}`;
    const stillLoading: boolean = ! error && (! accession
      || (doi && accession && accession.doi !== theDoi)
      || (uuid && accession && accession.uuid !== uuid));
92

Matija Obreza's avatar
Matija Obreza committed
93
94
    const hasLatLon = accession && accession.geo && accession.geo.latitude !== null && accession.geo.longitude !== null;

95
    return (
Oleksii Savran's avatar
Oleksii Savran committed
96
      <PageLayout withFooter>
Matija Obreza's avatar
Matija Obreza committed
97
        <ScrollToTopOnMount />
Matija Obreza's avatar
Matija Obreza committed
98
        <ContentHeader title={ t('accessions.public.p.display.title') } subtitle={ t('accessions.public.p.display.subTitle') } />
Matija Obreza's avatar
Matija Obreza committed
99

100
101
102
        { stillLoading ? <Loading /> :
          <div>
            { error && <div>{ JSON.stringify(error) }</div> }
Matija Obreza's avatar
Matija Obreza committed
103

104
105
106
107
            { accession &&
              <PageContents>
                <MainSection title={
                  <div>
Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
108
                    { t('accessions.common.modelName') }: { accession.accessionNumber }
109
110
111
112
                    <div className="float-right">
                        <ReduxCheckbox
                            label={
                                <b>
Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
113
                                    { isChecked ? t('accessions.public.p.display.removeFromMyList', {accessionNumber: accession.accessionNumber}) : t('accessions.public.p.display.addToMyList', {accessionNumber: accession.accessionNumber}) }
114
115
116
117
118
119
120
121
122
123
124
125
                                </b>
                            }
                            input={ {
                                value: isChecked,
                                onChange: this.onCheckboxChange,
                            } }
                        />
                    </div>
                  </div>
                  }
                >
                  <Properties>
Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
126
127
128
                    { accession.doi && <PropertiesItem title="accessions.public.p.display.DOI"><DOI noPrefix value={ accession.doi } /></PropertiesItem> }
                    <PropertiesItem title="accessions.common.acceNumb" >{ accession.accessionNumber }</PropertiesItem>
                    <PropertiesItem title="accessions.public.p.display.holdingInstitute">
129
130
131
                      <InstituteLink to={ accession.institute }>
                        { accession.institute.fullName }
                      </InstituteLink>
Matija Obreza's avatar
Matija Obreza committed
132
133
                      <span> &mdash; </span>
                      <CountryLink noflag country={ accession.institute.country }/>
134
                    </PropertiesItem>
Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
135
136
137
138
139
                    <PropertiesItem title="accessions.common.instituteCode">{ accession.institute.code }</PropertiesItem>
                    <PropertiesItem title="accessions.public.p.display.acquisitionDate"><McpdDate value={ accession.acquisitionDate } /></PropertiesItem>
                    { accession.countryOfOrigin && <PropertiesItem title="accessions.common.countryOfOrigin">{ <CountryLink country={ accession.countryOfOrigin }/> }</PropertiesItem> }
                    { accession.sampStat && <PropertiesItem title="accessions.common.sampStat">{ t(`accessions.common.sampleStatus.${accession.sampStat}`) }</PropertiesItem> }
                    { accession.storage && accession.storage.length > 0 && <PropertiesItem title="accessions.common.storageType">
140
                      { accession.storage.map((storage, i) => (
Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
141
                        <div key={ storage } style={ {width: '100%', paddingTop: '.25rem'} }>{ t(`accessions.common.storage.${storage}`) }</div>
142
143
                      )) }
                    </PropertiesItem> }
Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
144
145
146
147
                    <PropertiesItem title="accessions.public.p.display.availability" keepEmpty>{ t(`accessions.common.available.${accession.available}`) }</PropertiesItem>
                    <PropertiesItem title="accessions.public.p.display.ITPGRFAMLS" keepEmpty>{ t(`accessions.common.mlsStatus.${accession.mlsStatus}`) }</PropertiesItem>
                    <PropertiesItem title="accessions.public.p.display.donorInstitute">{ accession.donorCode }</PropertiesItem>
                    <PropertiesItem title="accessions.public.p.display.donorAccessionNumber">{ accession.donorNumb }</PropertiesItem>
Matija Obreza's avatar
Matija Obreza committed
148

Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
149
                    { accession.duplSite && accession.duplSite.length > 0 && <PropertiesItem title="accessions.public.p.display.safetyDuplicationInstitute">
150
                      { accession.duplSite.map((duplSite, i) => (
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
151
                        <div key={ duplSite } style={ {width: '100%', paddingTop: '.25rem'} }>{ duplSite }</div>
152
153
                      )) }
                    </PropertiesItem> }
Matija Obreza's avatar
Matija Obreza committed
154

Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
155
                    { accession.acceUrl && <PropertiesItem title="accessions.public.p.display.accessionURL"><ExternalLink link={ accession.acceUrl } /></PropertiesItem> }
156
157
                  </Properties>
                </MainSection>
Matija Obreza's avatar
Matija Obreza committed
158

Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
159
                <PageSection title="accessions.common.taxonomy">
160
                  <Properties>
Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
161
162
                    <PropertiesItem title="accessions.common.genus">{ accession.taxonomy.genus }</PropertiesItem>
                    <PropertiesItem title="accessions.common.species">
163
164
165
166
                      { accession.taxonomy.species }
                      { '' }
                      <Link to={ '/a' }>View <i>{ `${accession.taxonomy.genus} ${accession.taxonomy.species}` }</i> at { accession.institute.code }</Link>
                    </PropertiesItem>
Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
167
168
169
                    <PropertiesItem title="accessions.public.p.display.scientificName"><SciName taxa={ accession.taxonomy.taxonNameHtml } /></PropertiesItem>
                    { accession.crop && <PropertiesItem title="accessions.public.p.display.cropName"><CropChips crops={ accession.crop.shortName } /></PropertiesItem> }
                    <PropertiesItem title="accessions.public.p.display.providedCropName">{ accession.cropName }</PropertiesItem>
170
171
                  </Properties>
                </PageSection>
Matija Obreza's avatar
Cleanup    
Matija Obreza committed
172
173

                { (accession.donorCode || (accession.aliases && accession.aliases.length > 0)) &&
Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
174
                  <PageSection title="accessions.public.p.display.accessionNames">
175
                    <Properties>
Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
176
                      { accession.donorCode && <PropertiesItem title={ t('accessions.common.alias.DONORNUMB') }>{ accession.donorNumb } <em>{ accession.donorCode }</em></PropertiesItem> }
177
                      { accession.aliases && accession.aliases.map((alias) => (
Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
178
                        <PropertiesItem key={ alias.id } title={ t(`accessions.common.alias.${alias.aliasType}`) }>{ alias.name } <em>{ alias.usedBy }</em></PropertiesItem>
179
180
181
182
                      )) }
                    </Properties>
                  </PageSection>
                }
183

184
                { accession.coll &&
Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
185
                  <PageSection title="accessions.public.p.display.collectingInformation">
186
                    <Properties>
Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
187
188
                      { accession.countryOfOrigin && <PropertiesItem title="accessions.common.countryOfOrigin">{ <CountryLink country={ accession.countryOfOrigin }/> }</PropertiesItem> }
                      { accession.coll.collDate && <PropertiesItem key="collDate" title={ t(`accessions.common.coll.collDate`) }><McpdDate value={ accession.coll.collDate } /></PropertiesItem> }
189
190
191
                      { accession.coll &&
                        [ 'collMissId', 'collNumb', 'collSite', 'collSrc' ]
                          .filter((prop) => accession.coll[prop] !== null).map((prop) => (
Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
192
                          <PropertiesItem key={ prop } title={ t(`accessions.common.coll.${prop}`) }>{ accession.coll[prop] }</PropertiesItem>
193
                        ))
194
                      }
195
196
197
                      { accession.coll &&
                        [ 'collCode', 'collName' ]
                          .filter((prop) => accession.coll[prop].length).map((prop) => (
Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
198
                          <PropertiesItem key={ prop } title={ t(`accessions.common.coll.${prop}`) }>{ accession.coll[prop] }</PropertiesItem>
199
200
201
202
203
                        ))
                      }
                      { accession.geo &&
                        [ 'latitude', 'longitude', 'datum', 'method', 'uncertainty', 'elevation' ]
                          .filter((prop) => accession.geo[prop] !== null).map((prop) => (
Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
204
                          <PropertiesItem key={ prop } title={ t(`accessions.common.geo.${prop}`) }>{ accession.geo[prop] }</PropertiesItem>
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
                        ))
                      }
                    </Properties>

                    { hasLatLon &&
                      <LocationMap
                        location={
                          {
                            id: accession.geo.id,
                            lat: accession.geo.latitude,
                            lng: accession.geo.longitude,
                          }
                        }
                      />
                    }
                  </PageSection>
                }
Matija Obreza's avatar
Matija Obreza committed
222

Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
223
                { accession.remarks && accession.remarks.length > 0 && <PageSection title="accessions.public.p.display.remarks">
224
225
226
227
228
229
                  <Properties>
                    { accession.remarks && accession.remarks.map((remark) => (
                      <PropertiesItem key={ remark.id } title={ remark.fieldName }>{ remark.remark }</PropertiesItem>
                    )) }
                  </Properties>
                </PageSection> }
Matija Obreza's avatar
Matija Obreza committed
230

Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
231
                { pdci && <PdciTable pdci={ pdci } title="accessions.public.p.display.pdci"/> }
Matija Obreza's avatar
Matija Obreza committed
232

Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
233
                <PageSection title="accessions.public.p.display.metadata">
234
                  <Properties>
Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
235
236
237
238
                    <PropertiesItem title="common:label.UUID">{ `urn:uuid:${accession.uuid}` }</PropertiesItem>
                    <PropertiesItem title="accessions.public.p.display.permanentURL"><ExternalLink link={ `https://purl.org/germplasm/id/${accession.uuid}` } /></PropertiesItem>
                    <PropertiesItem title="common:label.lastUpdated"><PrettyDate value={ accession.lastModifiedDate } /></PropertiesItem>
                    <PropertiesItem title="common:label.created"><PrettyDate value={ accession.createdDate } /></PropertiesItem>
239
240
                  </Properties>
                </PageSection>
241
242
243
244
245

                <GridLayout>
                  { datasets && datasets.length > 0 &&
                  <PropertiesCard
                    small
Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
246
                    title="accessions.public.p.display.associatedDatasets"
247
                    propertyItemProps={ { keepEmpty: true } }
Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
248
                    propertiesList={ datasets.map((dataset) => ({ title: 'dataset.common.modelName', value: <DatasetLink to={ dataset } /> })) }
249
250
251
252
253
                  />
                  }
                  { subsets && subsets.length > 0 &&
                  <PropertiesCard
                    small
Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
254
                    title="accessions.public.p.display.associatedSubsets"
255
                    propertyItemProps={ { keepEmpty: true } }
Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
256
                    propertiesList={ subsets.map((subset) => ({ title: 'subset.common.modelName', value: <SubsetLink to={ subset } /> })) }
257
258
259
                  />
                  }
                </GridLayout>
260
261
262
              </PageContents>
            }
          </div>
Matija Obreza's avatar
Matija Obreza committed
263
        }
264
265
266
267
268
269
      </PageLayout>
    );
  }
}

const mapStateToProps = (state, ownProps) => ({
270
271
  accession: state.accessions.public.accession,
  error: state.accessions.public.accessionError,
272
  uuid: ownProps.match.params.uuid,
273
  doi: ownProps.match.params.doi,
274
  accessions: state.list.public.myList.accessions,
275
276
277
});

const mapDispatchToProps = (dispatch) => bindActionCreators({
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
278
279
  addAccessionToMyList,
  removeAccessionFromMyList,
280
281
282
283
  loadAccession,
}, dispatch);


Matija Obreza's avatar
Matija Obreza committed
284
export default connect(mapStateToProps, mapDispatchToProps)(translate()(BrowsePage));