DisplayPage.tsx 24.3 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
import { withStyles } from '@material-ui/core/styles';
6
7

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

11
12
13
// Constants
import { ROLE_USER } from 'constants/userRoles';

14
// Models
15
import AccessionDetails from 'model/accession/AccessionDetails';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
16
import RepositoryFile from 'model/repository/RepositoryFile';
17
import AccessionAuditLog from 'model/accession/AccessionAuditLog';
18
19

// UI
Matija Obreza's avatar
Matija Obreza committed
20
21
import PrettyDate from 'ui/common/time/PrettyDate';
import PageLayout, { PageContents, MainSection, PageSection } from 'ui/layout/PageLayout';
22
23
import ContentHeader from 'ui/common/heading/ContentHeader';
import Loading from 'ui/common/Loading';
Matija Obreza's avatar
Matija Obreza committed
24
25
26
27
28
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
29
import ReduxCheckbox from 'ui/common/checkbox';
30
import CropChips from 'crop/ui/c/CropChips';
31
import LocationMap from 'ui/common/LocationMap';
32
33
import {CountryLink, DatasetLink, InstituteLink, SubsetLink} from 'ui/genesys/Links';
import PropertiesCard from 'ui/common/PropertiesCard';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
34
import GridContainer from 'ui/layout/GridContainer';
35
import McpdDate from 'ui/common/time/McpdDate';
36
import PdciTable from './c/PdciTable';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
37
38
import ImageGalleryView from 'repository/ui/c/ImageGalleryView';
import Button from '@material-ui/core/Button/Button';
39
40
import AuditedInfo from 'ui/common/AuditedInfo';
import Authorize from 'ui/common/authorized/Authorize';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
41
42
43
import TemperatureChart from './c/TemperatureChart';
import PrecipitationChart from './c/PrecipitationChart';
import ClimateTable from './c/ClimateTable';
44
import ActionButton from 'ui/common/buttons/ActionButton';
Matija Obreza's avatar
Matija Obreza committed
45

46
47
48
49
const styles = (theme) => ({
  pageSection: {
    marginBottom: '1em',
  },
Matija Obreza's avatar
Matija Obreza committed
50
51
52
53
54
55
  selected: {
    background: '#c9e2cb',
  },
  historic: {
    background: '#ffe2e2 !important',
  },
56
57
});

58

59
60
61
interface IBrowsePageProps {
  t?: any;
  classes?: any;
62

63
  uuid: string;
64
  doi: string; // DOI comes from the route without the '10.'
65
  accession: AccessionDetails;
66
  auditLog: AccessionAuditLog;
67
68
  error: any;
  loadAccession: any;
69
  loadAccessionAuditLog: any;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
70
71
72
  accessions: any;
  addAccessionToMyList: any;
  removeAccessionFromMyList: any;
Matija Obreza's avatar
Matija Obreza committed
73
  applyFilters: any;
74
75
76
77
78
}

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

  protected static needs = [
79
    ({ params: { uuid, doi } }) => {
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
80
        return doi ? loadAccession({ doi: `10.${doi}` }) :  loadAccession({ uuid });
81
82
83
84
85
86
87
88
    },
  ];

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

  public componentWillMount() {
89
90
91
    const { doi, uuid, loadAccession } = this.props;
    const accession = this.props.accession ? this.props.accession.details : null;

92
93
94
95
    const theDoi = `10.${doi}`;
    if (doi && (! accession || theDoi !== accession.doi)) {
      loadAccession({ doi: theDoi });
    }
96
    if (uuid && (! accession || uuid !== accession.uuid)) {
97
      loadAccession({ uuid });
98
99
100
    }
  }

101
102
103
104
105
106
107
108
109
110
111
  private loadAuditLog = () => {
    const { doi, uuid, loadAccessionAuditLog } = this.props;

    const theDoi = `10.${doi}`;
    if (doi) {
      loadAccessionAuditLog({ doi: theDoi });
    } else {
      loadAccessionAuditLog({uuid});
    }
  }

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
112
  private onCheckboxChange = (event, checked) => {
113
      const {accession: {details: accession}, addAccessionToMyList, removeAccessionFromMyList} = this.props;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
114
115
116
117
118
119
120
      if (checked) {
          addAccessionToMyList(accession.uuid);
      } else {
          removeAccessionFromMyList(accession.uuid);
        }
  }

Matija Obreza's avatar
Matija Obreza committed
121
122
123
124
125
126
127

  private applyFilterForInstituteSpecies = () => {
    const { accession: {details: accession}, applyFilters } = this.props;
    const filter = {holder: {code: [ accession.institute.code ]}, taxa: { genus: [ accession.taxonomy.genus ], species: [ accession.taxonomy.species ] }};
    applyFilters(filter);
  }

128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
  private makeRange = (variable: number, diff: number) => {
    return {
      ge: Math.round(variable - diff),
      le: Math.round(variable + diff),
    };
  }

  private applyClimateFilters = () => {
    const { accession: {details: accession}, applyFilters } = this.props;
    // BIO1 = Annual Mean Temperature !!
    // BIO2 = Mean Diurnal Range (Mean of monthly (max temp - min temp))
    // BIO3 = Isothermality (BIO2/BIO7) (* 100)
    // BIO4 = Temperature Seasonality (standard deviation *100)
    // BIO5 = Max Temperature of Warmest Month
    // BIO6 = Min Temperature of Coldest Month
    // BIO7 = Temperature Annual Range (BIO5-BIO6)
    // BIO8 = Mean Temperature of Wettest Quarter
    // BIO9 = Mean Temperature of Driest Quarter
    // BIO10 = Mean Temperature of Warmest Quarter
    // BIO11 = Mean Temperature of Coldest Quarter
    // BIO12 = Annual Precipitation
    // BIO13 = Precipitation of Wettest Month
    // BIO14 = Precipitation of Driest Month
    // BIO15 = Precipitation Seasonality (Coefficient of Variation)
    // BIO16 = Precipitation of Wettest Quarter
    // BIO17 = Precipitation of Driest Quarter
    // BIO18 = Precipitation of Warmest Quarter !!
    // BIO19 = Precipitation of Coldest Quarter !!
    const tempDiff = 2;

    const filter = {
      taxa: {
        genus: [ accession.taxonomy.genus ],
        // species: [ accession.taxonomy.species ],
      },
      geo: {
        climate: {
          // temperature
          bio1: this.makeRange(accession.geo.climate.bio1, tempDiff),
          // bio2: this.makeRange(accession.geo.climate.bio2, tempDiff),
          bio4: this.makeRange(accession.geo.climate.bio4, accession.geo.climate.bio4 * .50),

          // bio7: this.makeRange(accession.geo.climate.bio7, tempDiff),
          // bio8: this.makeRange(accession.geo.climate.bio8, tempDiff),
          // bio9: this.makeRange(accession.geo.climate.bio9, tempDiff),
          // bio10: this.makeRange(accession.geo.climate.bio10, tempDiff),
          // bio11: this.makeRange(accession.geo.climate.bio11, tempDiff),
          // precipitation
          bio12: this.makeRange(accession.geo.climate.bio12, accession.geo.climate.bio12 * .25),
          // bio13: this.makeRange(accession.geo.climate.bio13, precDif),
          // bio14: this.makeRange(accession.geo.climate.bio14, precDif),
          // bio15: this.makeRange(accession.geo.climate.bio15, accession.geo.climate.bio15 * .25),
          bio18: this.makeRange(accession.geo.climate.bio18, accession.geo.climate.bio18 * .25),
          bio19: this.makeRange(accession.geo.climate.bio19, accession.geo.climate.bio19 * .25),
        },
      },
    };
    applyFilters(filter);
  }
Matija Obreza's avatar
Matija Obreza committed
187

188
  public render() {
189
190
191
192
    const { t, error, uuid, doi, accessions, auditLog, classes } = this.props;

    const { auditAccession, auditAccessionId, auditAccessionCollect, auditAccessionGeo } = auditLog || { auditAccession: {}, auditAccessionId: {}, auditAccessionCollect: {}, auditAccessionGeo: {} };

193
    const { details: accession, pdci, datasets, subsets, files, imageGallery } = this.props.accession ?
194
195
      this.props.accession
      :
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
196
      {details: null, pdci: null, datasets: null, subsets: null, files: null, imageGallery: null};
197

Matija Obreza's avatar
Matija Obreza committed
198
    const isChecked  =  accession && accessions && accessions.includes(accession.uuid);
199
200
201
202
    const theDoi = `10.${doi}`;
    const stillLoading: boolean = ! error && (! accession
      || (doi && accession && accession.doi !== theDoi)
      || (uuid && accession && accession.uuid !== uuid));
203

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

206
    return (
Oleksii Savran's avatar
Oleksii Savran committed
207
      <PageLayout withFooter>
Matija Obreza's avatar
Matija Obreza committed
208
        <ScrollToTopOnMount />
Matija Obreza's avatar
Matija Obreza committed
209
        <ContentHeader title={ t('accessions.public.p.display.title') } subtitle={ t('accessions.public.p.display.subTitle') } />
Matija Obreza's avatar
Matija Obreza committed
210

211
212
213
        { stillLoading ? <Loading /> :
          <div>
            { error && <div>{ JSON.stringify(error) }</div> }
Matija Obreza's avatar
Matija Obreza committed
214

215
            { accession &&
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
216
              <PageContents className="pt-1rem">
Matija Obreza's avatar
Matija Obreza committed
217
                <MainSection className={ isChecked ? classes.selected : accession.historic ?  classes.historic : '' } title={
218
                  <div>
Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
219
                    { t('accessions.common.modelName') }: { accession.accessionNumber }
220
                    <div className="float-right">
221
222
223
                        <Authorize role={ ROLE_USER }>
                            <Button className="mr-20" variant="contained" onClick={ this.loadAuditLog }>{ t('accessions.public.p.display.loadChanges') }</Button>
                        </Authorize>
224
225
226
                        <ReduxCheckbox
                            label={
                                <b>
Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
227
                                    { isChecked ? t('accessions.public.p.display.removeFromMyList', {accessionNumber: accession.accessionNumber}) : t('accessions.public.p.display.addToMyList', {accessionNumber: accession.accessionNumber}) }
228
229
230
231
232
233
234
235
236
237
238
239
                                </b>
                            }
                            input={ {
                                value: isChecked,
                                onChange: this.onCheckboxChange,
                            } }
                        />
                    </div>
                  </div>
                  }
                >
                  <Properties>
240
                    { accession.doi && <PropertiesItem title={ t('accessions.public.p.display.DOI') }><DOI noPrefix value={ accession.doi } /></PropertiesItem> }
241
242
243
244
                    <PropertiesItem title={ t('accessions.common.acceNumb') } >
                      { accession.accessionNumber }
                      <AuditedInfo info={ auditAccession.accessionNumber }/>
                    </PropertiesItem>
245
                    <PropertiesItem title={ t('accessions.public.p.display.holdingInstitute') }>
246
247
248
                      <InstituteLink to={ accession.institute }>
                        { accession.institute.fullName }
                      </InstituteLink>
Matija Obreza's avatar
Matija Obreza committed
249
250
                      <span> &mdash; </span>
                      <CountryLink noflag country={ accession.institute.country }/>
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
                      <AuditedInfo info={ auditAccession.institute }/>
                    </PropertiesItem>
                    { accession.historic &&
                      <PropertiesItem className={ accession.historic ?  classes.historic : '' } title={ t('accessions.public.p.display.historic') }>
                        { t('accessions.public.p.display.isHistoric') }
                        <AuditedInfo info={ auditAccession.historic }/>
                      </PropertiesItem>
                    }
                    <PropertiesItem title={ t('accessions.common.instituteCode') }>
                      { accession.institute.code }
                      <AuditedInfo info={ auditAccession.instituteCode }/>
                    </PropertiesItem>
                    <PropertiesItem title={ t('accessions.public.p.display.acquisitionDate') }>
                      <McpdDate value={ accession.acquisitionDate } />
                      <AuditedInfo info={ auditAccession.acquisitionDate }/>
266
                    </PropertiesItem>
267
268
269
270
271
272
273
                    { accession.countryOfOrigin && <PropertiesItem title={ t('accessions.common.countryOfOrigin') }>{ <CountryLink country={ accession.countryOfOrigin }/> }<AuditedInfo info={ auditAccession.countryOfOrigin }/></PropertiesItem> }
                    { accession.sampStat &&
                      <PropertiesItem title={ t('accessions.common.sampStat') }>
                        { t(`accessions.common.sampleStatus.${accession.sampStat}`) }
                        <AuditedInfo info={ auditAccession.sampStat }/>
                      </PropertiesItem>
                    }
274
                    { accession.storage && accession.storage.length > 0 && <PropertiesItem title={ t('accessions.common.storageType') }>
275
                      { accession.storage.map((storage, i) => (
Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
276
                        <div key={ storage } style={ {width: '100%', paddingTop: '.25rem'} }>{ t(`accessions.common.storage.${storage}`) }</div>
277
278
                      )) }
                    </PropertiesItem> }
279
280
281
282
283
284
285
286
                    <PropertiesItem title={ t('accessions.public.p.display.availability') } keepEmpty>
                      { t(`accessions.common.available.${accession.available}`) }
                      <AuditedInfo info={ auditAccession.available }/>
                    </PropertiesItem>
                    <PropertiesItem title={ t('accessions.public.p.display.ITPGRFAMLS') } keepEmpty>
                      { t(`accessions.common.mlsStatus.${accession.mlsStatus}`) }
                      <AuditedInfo info={ auditAccession.mlsStatus }/>
                    </PropertiesItem>
287
288
289
290
291
292
293
294
295
296
297
298
                    { accession.donorCode &&
                      <PropertiesItem title={ t('accessions.public.p.display.donorInstitute') }>
                        { accession.donorCode }
                        <AuditedInfo info={ auditAccession.donorCode }/>
                      </PropertiesItem>
                    }
                    { accession.donorNumb &&
                      <PropertiesItem title={ t('accessions.public.p.display.donorAccessionNumber') }>
                        { accession.donorNumb }
                        <AuditedInfo info={ auditAccession.donorNumb }/>
                      </PropertiesItem>
                    }
299
                    { accession.duplSite && accession.duplSite.length > 0 && <PropertiesItem title={ t('accessions.public.p.display.safetyDuplicationInstitute') }>
300
                      { accession.duplSite.map((duplSite, i) => (
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
301
                        <div key={ duplSite } style={ {width: '100%', paddingTop: '.25rem'} }>{ duplSite }</div>
302
303
                      )) }
                    </PropertiesItem> }
Matija Obreza's avatar
Matija Obreza committed
304

305
                    { accession.acceUrl && <PropertiesItem title={ t('accessions.public.p.display.accessionURL') }><ExternalLink link={ accession.acceUrl } /></PropertiesItem> }
306
307
                  </Properties>
                </MainSection>
Matija Obreza's avatar
Matija Obreza committed
308

309
310
311
312
                { imageGallery &&
                  <ImageGalleryView className={ classes.pageSection } imageGallery={ imageGallery }/>
                }

313
                <PageSection title={ t('accessions.common.taxonomy') }>
314
                  <Properties>
315
316
317
318
                    <PropertiesItem title={ t('accessions.common.genus') }>
                      { accession.taxonomy.genus }
                      <AuditedInfo info={ auditAccession.genus }/>
                    </PropertiesItem>
319
                    <PropertiesItem title={ t('accessions.common.species') }>
320
321
                      { accession.taxonomy.species }
                      { '' }
Matija Obreza's avatar
Matija Obreza committed
322
                      <a onClick={ this.applyFilterForInstituteSpecies }>View <i>{ `${accession.taxonomy.genus} ${accession.taxonomy.species}` }</i> at { accession.institute.code }</a>
323
                    </PropertiesItem>
324
325
326
                    <PropertiesItem title={ t('accessions.public.p.display.scientificName') }><SciName taxa={ accession.taxonomy.taxonNameHtml } /></PropertiesItem>
                    { accession.crop && <PropertiesItem title={ t('accessions.public.p.display.cropName') }><CropChips crops={ accession.crop.shortName } /></PropertiesItem> }
                    <PropertiesItem title={ t('accessions.public.p.display.providedCropName') }>{ accession.cropName }</PropertiesItem>
327
328
                  </Properties>
                </PageSection>
Matija Obreza's avatar
Cleanup    
Matija Obreza committed
329
330

                { (accession.donorCode || (accession.aliases && accession.aliases.length > 0)) &&
331
                  <PageSection title={ t('accessions.public.p.display.accessionNames') }>
332
                    <Properties>
Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
333
                      { accession.donorCode && <PropertiesItem title={ t('accessions.common.alias.DONORNUMB') }>{ accession.donorNumb } <em>{ accession.donorCode }</em></PropertiesItem> }
334
                      { accession.aliases && accession.aliases.map((alias) => (
Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
335
                        <PropertiesItem key={ alias.id } title={ t(`accessions.common.alias.${alias.aliasType}`) }>{ alias.name } <em>{ alias.usedBy }</em></PropertiesItem>
336
337
338
339
                      )) }
                    </Properties>
                  </PageSection>
                }
340

341
                { accession.coll &&
342
                  <PageSection title={ t('accessions.public.p.display.collectingInformation') }>
343
                    <Properties>
344
345
346
347
348
349
350
351
352
353
354
355
                      { accession.countryOfOrigin &&
                        <PropertiesItem title={ t('accessions.common.countryOfOrigin') }>
                          <CountryLink country={ accession.countryOfOrigin }/>
                          <AuditedInfo info={ auditAccessionCollect.countryOfOrigin }/>
                        </PropertiesItem>
                      }
                      { accession.coll.collDate &&
                        <PropertiesItem key="collDate" title={ t(`accessions.common.coll.collDate`) }>
                          <McpdDate value={ accession.coll.collDate } />
                          <AuditedInfo info={ auditAccessionCollect.collDate }/>
                        </PropertiesItem>
                      }
Oleksii Savran's avatar
Oleksii Savran committed
356
357
358
359
360
361
                      { accession.coll.collSrc &&
                        <PropertiesItem key="collSrc" title={ t(`accessions.common.coll.collSrc`) }>
                          { t(`accessions.common.collectingSource.${accession.coll.collSrc}`) }
                          <AuditedInfo info={ auditAccessionCollect.collSrc }/>
                        </PropertiesItem>
                      }
362
                      { accession.coll &&
Oleksii Savran's avatar
Oleksii Savran committed
363
                        [ 'collMissId', 'collNumb', 'collSite' ]
364
                          .filter((prop) => accession.coll[prop] !== null).map((prop) => (
365
366
367
368
                          <PropertiesItem key={ prop } title={ t(`accessions.common.coll.${prop}`) }>
                            { accession.coll[prop] }
                            <AuditedInfo info={ auditAccessionCollect[prop] }/>
                          </PropertiesItem>
369
                        ))
370
                      }
371
372
373
                      { accession.coll &&
                        [ 'collCode', 'collName' ]
                          .filter((prop) => accession.coll[prop].length).map((prop) => (
374
375
376
377
                          <PropertiesItem key={ prop } title={ t(`accessions.common.coll.${prop}`) }>
                            { accession.coll[prop] }
                            <AuditedInfo info={ auditAccessionCollect[prop] }/>
                          </PropertiesItem>
378
379
380
381
382
                        ))
                      }
                      { accession.geo &&
                        [ 'latitude', 'longitude', 'datum', 'method', 'uncertainty', 'elevation' ]
                          .filter((prop) => accession.geo[prop] !== null).map((prop) => (
383
384
385
386
                          <PropertiesItem key={ prop } title={ t(`accessions.common.geo.${prop}`) }>
                            { accession.geo[prop] }
                            <AuditedInfo info={ auditAccessionGeo[prop] }/>
                          </PropertiesItem>
387
388
389
390
391
                        ))
                      }
                    </Properties>

                    { hasLatLon &&
Maxym Borodenko's avatar
Maxym Borodenko committed
392
                      <LocationMap locations={ [{ id: accession.geo.id, lat: accession.geo.latitude, lng: accession.geo.longitude }] }/>
393
394
395
                    }
                  </PageSection>
                }
Matija Obreza's avatar
Matija Obreza committed
396

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
                { accession.geo && accession.geo.climate &&
                  <PageSection title={ t('accessions.public.p.display.climateAtCollection') }>
                    <GridContainer className="container-spacing-vertical">
                      <TemperatureChart halfWidth climate={ accession.geo.climate }/>
                      <PrecipitationChart halfWidth climate={ accession.geo.climate }/>
                    </GridContainer>
                    <div>
                      <ClimateTable climate={ accession.geo.climate }/>
                    </div>
                  </PageSection>
                }

                { accession.geo && accession.geo.climate &&
                  <PageSection title={ t('accessions.public.p.display.additionalInfo') }>
                    <Properties>
                      { [...Array(19).keys()].map((i) => (
                        <PropertiesItem md numeric key={ `month-${i}` } title={ t(`accessions.climate.bio${i + 1}`) }>
                          { accession.geo.climate[`bio${i + 1}`] && Number(accession.geo.climate[`bio${i + 1}`]).toFixed(1) }
                        </PropertiesItem>
                      )) }
                    </Properties>
418
419
420
                    <div>
                      <ActionButton action={ this.applyClimateFilters } title="View accessions with similar climate" />
                    </div>
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
421
422
423
                  </PageSection>
                }

424
                { accession.remarks && accession.remarks.length > 0 && <PageSection title={ t('accessions.public.p.display.remarks') }>
425
426
427
428
429
430
                  <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
431

432
433
434
435
436
437
                { files &&
                  <PageSection title={ t('accessions.public.p.display.relatedResources') }>
                    <Properties>
                      { files.map((e: RepositoryFile) => (
                        <PropertiesItem key={ e.uuid } title={
                          <a href={ `/proxy/api/v1/repository/download/${e.uuid}` }>
438
                            <Button variant="contained" component="span">
439
440
441
442
443
444
445
446
447
448
449
                              { t('common:action.download') }
                            </Button>
                          </a>
                        }>
                          <b>{ e.originalFilename }</b>
                        </PropertiesItem>
                      )) }
                    </Properties>
                  </PageSection>
                }

450
                { pdci && <PdciTable pdci={ pdci } title={ t('accessions.public.p.display.pdci') }/> }
Matija Obreza's avatar
Matija Obreza committed
451

452
                <PageSection title={ t('accessions.public.p.display.metadata') }>
453
                  <Properties>
454
455
456
457
                    <PropertiesItem title={ t('common:label.UUID') }>
                      { `urn:uuid:${accession.uuid}` }
                      <AuditedInfo info={ auditAccessionId.uuid }/>
                    </PropertiesItem>
458
459
460
                    <PropertiesItem title={ t('accessions.public.p.display.permanentURL') }><ExternalLink link={ `https://purl.org/germplasm/id/${accession.uuid}` } /></PropertiesItem>
                    <PropertiesItem title={ t('common:label.lastUpdated') }><PrettyDate value={ accession.lastModifiedDate } /></PropertiesItem>
                    <PropertiesItem title={ t('common:label.created') }><PrettyDate value={ accession.createdDate } /></PropertiesItem>
461
462
                  </Properties>
                </PageSection>
463

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
464
                <GridContainer className="mb-15">
465
466
467
                  { datasets && datasets.length > 0 &&
                  <PropertiesCard
                    small
468
                    title={ t('accessions.public.p.display.associatedDatasets') }
469
                    propertyItemProps={ { keepEmpty: true } }
Matija Obreza's avatar
Matija Obreza committed
470
                    propertiesList={ datasets.map((dataset) => ({ value: <DatasetLink to={ dataset } /> })) }
471
472
473
474
475
                  />
                  }
                  { subsets && subsets.length > 0 &&
                  <PropertiesCard
                    small
476
                    title={ t('accessions.public.p.display.associatedSubsets') }
477
                    propertyItemProps={ { keepEmpty: true } }
Matija Obreza's avatar
Matija Obreza committed
478
                    propertiesList={ subsets.map((subset) => ({ value: <SubsetLink to={ subset } /> })) }
479
480
                  />
                  }
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
481
                </GridContainer>
482
483
484
              </PageContents>
            }
          </div>
Matija Obreza's avatar
Matija Obreza committed
485
        }
486
487
488
489
490
491
      </PageLayout>
    );
  }
}

const mapStateToProps = (state, ownProps) => ({
492
  accession: state.accessions.public.accession,
493
  auditLog: state.accessions.public.auditLog,
494
  error: state.accessions.public.accessionError,
495
  uuid: ownProps.match.params.uuid,
496
  doi: ownProps.match.params.doi,
497
  accessions: state.list.public.myList.accessions,
498
499
500
});

const mapDispatchToProps = (dispatch) => bindActionCreators({
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
501
502
  addAccessionToMyList,
  removeAccessionFromMyList,
503
  loadAccession,
504
  loadAccessionAuditLog,
Matija Obreza's avatar
Matija Obreza committed
505
  applyFilters,
506
507
508
}, dispatch);


509
export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(translate()(BrowsePage)));