DisplayPage.tsx 24.6 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';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
44
import PageTitle from 'ui/common/PageTitle';
45
import ActionButton from 'ui/common/buttons/ActionButton';
Matija Obreza's avatar
Matija Obreza committed
46

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

59

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

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

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

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

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

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

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

102
103
104
105
106
107
108
109
110
111
112
  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
113
  private onCheckboxChange = (event, checked) => {
114
      const {accession: {details: accession}, addAccessionToMyList, removeAccessionFromMyList} = this.props;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
115
116
117
118
119
120
121
      if (checked) {
          addAccessionToMyList(accession.uuid);
      } else {
          removeAccessionFromMyList(accession.uuid);
        }
  }

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

  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);
  }

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
187
  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
188

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

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

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

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

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

207
    return (
Oleksii Savran's avatar
Oleksii Savran committed
208
      <PageLayout withFooter>
Matija Obreza's avatar
Matija Obreza committed
209
        <ScrollToTopOnMount />
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
210
211
212
213
214
        <PageTitle title={ !stillLoading ? accession.accessionNumber : t('common:label.loading', { what: t('accessions.public.p.display.title') }) } />
        <ContentHeader
          title={ !stillLoading ? accession.accessionNumber : t('common:label.loading', { what: t('accessions.public.p.display.title') }) }
          subtitle={ t('accessions.public.p.display.subTitle') }
        />
Matija Obreza's avatar
Matija Obreza committed
215

216
217
218
        { stillLoading ? <Loading /> :
          <div>
            { error && <div>{ JSON.stringify(error) }</div> }
Matija Obreza's avatar
Matija Obreza committed
219

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

310
                    { accession.acceUrl && <PropertiesItem title={ t('accessions.public.p.display.accessionURL') }><ExternalLink link={ accession.acceUrl } /></PropertiesItem> }
311
312
                  </Properties>
                </MainSection>
Matija Obreza's avatar
Matija Obreza committed
313

314
315
316
317
                { imageGallery &&
                  <ImageGalleryView className={ classes.pageSection } imageGallery={ imageGallery }/>
                }

318
                <PageSection title={ t('accessions.common.taxonomy') }>
319
                  <Properties>
320
321
322
323
                    <PropertiesItem title={ t('accessions.common.genus') }>
                      { accession.taxonomy.genus }
                      <AuditedInfo info={ auditAccession.genus }/>
                    </PropertiesItem>
324
                    <PropertiesItem title={ t('accessions.common.species') }>
325
326
                      { accession.taxonomy.species }
                      { '' }
Matija Obreza's avatar
Matija Obreza committed
327
                      <a onClick={ this.applyFilterForInstituteSpecies }>View <i>{ `${accession.taxonomy.genus} ${accession.taxonomy.species}` }</i> at { accession.institute.code }</a>
328
                    </PropertiesItem>
329
330
331
                    <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>
332
333
                  </Properties>
                </PageSection>
Matija Obreza's avatar
Cleanup    
Matija Obreza committed
334
335

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

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

                    { hasLatLon &&
Maxym Borodenko's avatar
Maxym Borodenko committed
397
                      <LocationMap locations={ [{ id: accession.geo.id, lat: accession.geo.latitude, lng: accession.geo.longitude }] }/>
398
399
400
                    }
                  </PageSection>
                }
Matija Obreza's avatar
Matija Obreza committed
401

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
                { 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>
423
424
425
                    <div>
                      <ActionButton action={ this.applyClimateFilters } title="View accessions with similar climate" />
                    </div>
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
426
427
428
                  </PageSection>
                }

429
                { accession.remarks && accession.remarks.length > 0 && <PageSection title={ t('accessions.public.p.display.remarks') }>
430
431
432
433
434
435
                  <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
436

437
438
439
440
441
442
                { 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}` }>
443
                            <Button variant="contained" component="span">
444
445
446
447
448
449
450
451
452
453
454
                              { t('common:action.download') }
                            </Button>
                          </a>
                        }>
                          <b>{ e.originalFilename }</b>
                        </PropertiesItem>
                      )) }
                    </Properties>
                  </PageSection>
                }

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

457
                <PageSection title={ t('accessions.public.p.display.metadata') }>
458
                  <Properties>
459
460
461
462
                    <PropertiesItem title={ t('common:label.UUID') }>
                      { `urn:uuid:${accession.uuid}` }
                      <AuditedInfo info={ auditAccessionId.uuid }/>
                    </PropertiesItem>
463
464
465
                    <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>
466
467
                  </Properties>
                </PageSection>
468

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

const mapStateToProps = (state, ownProps) => ({
497
  accession: state.accessions.public.accession,
498
  auditLog: state.accessions.public.auditLog,
499
  error: state.accessions.public.accessionError,
500
  uuid: ownProps.match.params.uuid,
501
  doi: ownProps.match.params.doi,
502
  accessions: state.list.public.myList.accessions,
503
504
505
});

const mapDispatchToProps = (dispatch) => bindActionCreators({
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
506
507
  addAccessionToMyList,
  removeAccessionFromMyList,
508
  loadAccession,
509
  loadAccessionAuditLog,
Matija Obreza's avatar
Matija Obreza committed
510
  applyFilters,
511
512
513
}, dispatch);


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