DisplayPage.tsx 25 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
import navigateTo from 'actions/navigation';
11

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

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

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

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

60

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

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

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

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

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

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

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

104
105
106
107
108
109
110
111
112
  public componentWillReceiveProps(nextProps): void {
    const {uuid, doi, navigateTo} = this.props;
    const accession = this.props.accession ? this.props.accession.details : null;

    if (accession && accession.doi && !doi && accession.uuid === uuid) {
      navigateTo(`/${accession.doi}`);
    }
  }

113
114
115
116
117
118
119
120
121
122
123
  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
124
  private onCheckboxChange = (event, checked) => {
125
      const {accession: {details: accession}, addAccessionToMyList, removeAccessionFromMyList} = this.props;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
126
127
128
129
130
131
132
      if (checked) {
          addAccessionToMyList(accession.uuid);
      } else {
          removeAccessionFromMyList(accession.uuid);
        }
  }

Matija Obreza's avatar
Matija Obreza committed
133
134
135
136
137
138
139

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

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
188
189
190
191
192
193
194
195
196
197
198
  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
199

200
  public render() {
201
202
203
204
    const { t, error, uuid, doi, accessions, auditLog, classes } = this.props;

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

205
    const { details: accession, pdci, datasets, subsets, files, imageGallery } = this.props.accession ?
206
207
      this.props.accession
      :
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
208
      {details: null, pdci: null, datasets: null, subsets: null, files: null, imageGallery: null};
209

Matija Obreza's avatar
Matija Obreza committed
210
    const isChecked  =  accession && accessions && accessions.includes(accession.uuid);
211
212
213
214
    const theDoi = `10.${doi}`;
    const stillLoading: boolean = ! error && (! accession
      || (doi && accession && accession.doi !== theDoi)
      || (uuid && accession && accession.uuid !== uuid));
215

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

218
    return (
Oleksii Savran's avatar
Oleksii Savran committed
219
      <PageLayout withFooter>
Matija Obreza's avatar
Matija Obreza committed
220
        <ScrollToTopOnMount />
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
221
222
223
224
225
        <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
226

227
228
229
        { stillLoading ? <Loading /> :
          <div>
            { error && <div>{ JSON.stringify(error) }</div> }
Matija Obreza's avatar
Matija Obreza committed
230

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

321
                    { accession.acceUrl && <PropertiesItem title={ t('accessions.public.p.display.accessionURL') }><ExternalLink link={ accession.acceUrl } /></PropertiesItem> }
322
323
                  </Properties>
                </MainSection>
Matija Obreza's avatar
Matija Obreza committed
324

325
326
327
328
                { imageGallery &&
                  <ImageGalleryView className={ classes.pageSection } imageGallery={ imageGallery }/>
                }

329
                <PageSection title={ t('accessions.common.taxonomy') }>
330
                  <Properties>
331
332
333
334
                    <PropertiesItem title={ t('accessions.common.genus') }>
                      { accession.taxonomy.genus }
                      <AuditedInfo info={ auditAccession.genus }/>
                    </PropertiesItem>
335
                    <PropertiesItem title={ t('accessions.common.species') }>
336
337
                      { accession.taxonomy.species }
                      { '' }
Matija Obreza's avatar
Matija Obreza committed
338
                      <a onClick={ this.applyFilterForInstituteSpecies }>View <i>{ `${accession.taxonomy.genus} ${accession.taxonomy.species}` }</i> at { accession.institute.code }</a>
339
                    </PropertiesItem>
340
341
342
                    <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>
343
344
                  </Properties>
                </PageSection>
Matija Obreza's avatar
Cleanup  
Matija Obreza committed
345
346

                { (accession.donorCode || (accession.aliases && accession.aliases.length > 0)) &&
347
                  <PageSection title={ t('accessions.public.p.display.accessionNames') }>
348
                    <Properties>
Viacheslav Pavlov's avatar
i18n  
Viacheslav Pavlov committed
349
                      { accession.donorCode && <PropertiesItem title={ t('accessions.common.alias.DONORNUMB') }>{ accession.donorNumb } <em>{ accession.donorCode }</em></PropertiesItem> }
350
                      { accession.aliases && accession.aliases.map((alias) => (
Viacheslav Pavlov's avatar
i18n  
Viacheslav Pavlov committed
351
                        <PropertiesItem key={ alias.id } title={ t(`accessions.common.alias.${alias.aliasType}`) }>{ alias.name } <em>{ alias.usedBy }</em></PropertiesItem>
352
353
354
355
                      )) }
                    </Properties>
                  </PageSection>
                }
356

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

                    { hasLatLon &&
Maxym Borodenko's avatar
Maxym Borodenko committed
408
                      <LocationMap locations={ [{ id: accession.geo.id, lat: accession.geo.latitude, lng: accession.geo.longitude }] }/>
409
410
411
                    }
                  </PageSection>
                }
Matija Obreza's avatar
Matija Obreza committed
412

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
                { 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>
434
435
436
                    <div>
                      <ActionButton action={ this.applyClimateFilters } title="View accessions with similar climate" />
                    </div>
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
437
438
439
                  </PageSection>
                }

440
                { accession.remarks && accession.remarks.length > 0 && <PageSection title={ t('accessions.public.p.display.remarks') }>
441
442
443
444
445
446
                  <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
447

448
449
450
451
452
453
                { 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}` }>
454
                            <Button variant="contained" component="span">
455
456
457
458
459
460
461
462
463
464
465
                              { t('common:action.download') }
                            </Button>
                          </a>
                        }>
                          <b>{ e.originalFilename }</b>
                        </PropertiesItem>
                      )) }
                    </Properties>
                  </PageSection>
                }

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

468
                <PageSection title={ t('accessions.public.p.display.metadata') }>
469
                  <Properties>
470
471
472
473
                    <PropertiesItem title={ t('common:label.UUID') }>
                      { `urn:uuid:${accession.uuid}` }
                      <AuditedInfo info={ auditAccessionId.uuid }/>
                    </PropertiesItem>
474
475
476
                    <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>
477
478
                  </Properties>
                </PageSection>
479

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
480
                <GridContainer className="mb-15">
481
482
483
                  { datasets && datasets.length > 0 &&
                  <PropertiesCard
                    small
484
                    title={ t('accessions.public.p.display.associatedDatasets') }
485
                    propertyItemProps={ { keepEmpty: true } }
Matija Obreza's avatar
Matija Obreza committed
486
                    propertiesList={ datasets.map((dataset) => ({ value: <DatasetLink to={ dataset } /> })) }
487
488
489
490
491
                  />
                  }
                  { subsets && subsets.length > 0 &&
                  <PropertiesCard
                    small
492
                    title={ t('accessions.public.p.display.associatedSubsets') }
493
                    propertyItemProps={ { keepEmpty: true } }
Matija Obreza's avatar
Matija Obreza committed
494
                    propertiesList={ subsets.map((subset) => ({ value: <SubsetLink to={ subset } /> })) }
495
496
                  />
                  }
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
497
                </GridContainer>
498
499
500
              </PageContents>
            }
          </div>
Matija Obreza's avatar
Matija Obreza committed
501
        }
502
503
504
505
506
507
      </PageLayout>
    );
  }
}

const mapStateToProps = (state, ownProps) => ({
508
  accession: state.accessions.public.accession,
509
  auditLog: state.accessions.public.auditLog,
510
  error: state.accessions.public.accessionError,
511
  uuid: ownProps.match.params.uuid,
512
  doi: ownProps.match.params.doi,
513
  accessions: state.list.public.myList.accessions,
514
515
516
});

const mapDispatchToProps = (dispatch) => bindActionCreators({
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
517
518
  addAccessionToMyList,
  removeAccessionFromMyList,
519
  loadAccession,
520
  loadAccessionAuditLog,
Matija Obreza's avatar
Matija Obreza committed
521
  applyFilters,
522
  navigateTo,
523
524
525
}, dispatch);


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