AccessionDetailsPage.tsx 14.8 KB
Newer Older
Matija Obreza's avatar
Matija Obreza committed
1
import React from 'react';
Oleksii Savran's avatar
Redux    
Oleksii Savran committed
2
import { connect } from 'react-redux';
3
import {Link} from "react-router-dom";
Matija Obreza's avatar
Matija Obreza committed
4

5
import { AccessionService } from '@genesys-pgr/client/service';
Oleksii Savran's avatar
Oleksii Savran committed
6
import { Property } from 'ui/common/Property';
7
import AccessionDetails from '@genesys-pgr/client/model/accession/AccessionDetails';
8
import { WithTranslation, withTranslation } from 'react-i18next';
Matija Obreza's avatar
Matija Obreza committed
9
import { canAddToCart, LocalStorageCart } from 'utilities';
10
import { WithConfig } from 'config/config';
Maksym Tishchenko's avatar
Maksym Tishchenko committed
11
import { CountryName } from 'ui/common/CountryName';
Maksym Tishchenko's avatar
Maksym Tishchenko committed
12
13
import GrinSpecies from 'ui/common/GrinSpecies';
import PdciTable from 'ui/common/PdciTable';
Oleksii Savran's avatar
Oleksii Savran committed
14
import LocationMap from 'map/LocationMap';
Maksym Tishchenko's avatar
Maksym Tishchenko committed
15
import Loading from 'ui/common/Loading';
Maksym Tishchenko's avatar
Maksym Tishchenko committed
16
import PageTitle from 'ui/common/PageTitle';
Maksym Tishchenko's avatar
Maksym Tishchenko committed
17

Matija Obreza's avatar
Matija Obreza committed
18
interface AccessionDetailsPageState {
Maksym Tishchenko's avatar
Maksym Tishchenko committed
19
20
21
  accession: AccessionDetails;
  cartItems: string[];
}
Matija Obreza's avatar
Matija Obreza committed
22

Matija Obreza's avatar
Matija Obreza committed
23
interface AccessionDetailsPageProps {
Matija Obreza's avatar
Matija Obreza committed
24
25
26
  match: any;
}

Matija Obreza's avatar
Matija Obreza committed
27
class AccessionDetailsPage extends React.Component<AccessionDetailsPageProps & WithTranslation & WithConfig, AccessionDetailsPageState> {
Matija Obreza's avatar
Matija Obreza committed
28
29
30
31
32
  public constructor(props) {
    super(props);
  }

  public state = {
Maksym Tishchenko's avatar
Maksym Tishchenko committed
33
34
    accession: null,
    cartItems: LocalStorageCart.getCartItemsLS(),
Matija Obreza's avatar
Matija Obreza committed
35
36
37
38
  };

  public componentDidMount() {
    this.loadData(this.props.match.params.uuid);
Maksym Tishchenko's avatar
Maksym Tishchenko committed
39
40
41
42
43
44
45
46
47
48
    if (typeof window !== 'undefined') {
      window.addEventListener('storage', this.handleLocalStorageUpdate);
      this.receiveData();
    }
  }

  public componentWillUnmount() {
    if (typeof window !== 'undefined') {
      window.removeEventListener('storage', this.handleLocalStorageUpdate);
    }
Matija Obreza's avatar
Matija Obreza committed
49
50
  }

Maksym Tishchenko's avatar
Maksym Tishchenko committed
51
52
53
54
55
56
57
58
59
60
  private handleLocalStorageUpdate = (e: StorageEvent) => {
    if (e.key === LocalStorageCart.LS_KEY) {
      this.receiveData();
    }
  };

  private receiveData = () => {
    this.setState({ cartItems: LocalStorageCart.getCartItemsLS() });
  };

Matija Obreza's avatar
Matija Obreza committed
61
62
63
64
65
66
67
68
69
70
71
72
  private loadData = (uuid: string): Promise<void> => {
    return AccessionService
      .getDetailsByUuid(uuid)
      .then((data) => {
        console.log('accession: ', data);
        this.setState({ accession: data });
      })
      .catch((e) => {
        console.log('Api call failed: ', e);
      });
  };

Maksym Tishchenko's avatar
Maksym Tishchenko committed
73
74
75
76
77
78
79
80
81
82
  private addToCart = (e: React.MouseEvent<HTMLButtonElement>) => {
    LocalStorageCart.addToCart(e.currentTarget.getAttribute('data-uuid'));
    this.setState( { cartItems: LocalStorageCart.getCartItemsLS() } )
  };
  private removeFromCart = (e: React.MouseEvent<HTMLButtonElement>) => {
    LocalStorageCart.removeFromCart(e.currentTarget.getAttribute('data-uuid'));
    this.setState( { cartItems: LocalStorageCart.getCartItemsLS() } )
  }

  private renderAddToCart = () => {
Matija Obreza's avatar
Matija Obreza committed
83
    const { accession } = this.state;
Maksym Tishchenko's avatar
Maksym Tishchenko committed
84
85
    const { t } = this.props;

Matija Obreza's avatar
Matija Obreza committed
86
    const canAdd = canAddToCart(accession.details);
Maksym Tishchenko's avatar
Maksym Tishchenko committed
87

88
    return !accession.details.historic && <button
Maksym Tishchenko's avatar
Maksym Tishchenko committed
89
      type="button"
90
      disabled={ !canAdd }
Maksym Tishchenko's avatar
Maksym Tishchenko committed
91
92
93
94
95
      name={ `button-add-${accession.details.uuid}` }
      data-uuid={ accession.details.uuid }
      className="btn btn-primary"
      onClick={ this.addToCart }
    >
Matija Obreza's avatar
Matija Obreza committed
96
      { canAdd ? t('cart.addToCart') : t('list.notAvailable') }
Maksym Tishchenko's avatar
Maksym Tishchenko committed
97
98
99
100
101
    </button>
  }

  public render() {
    const { accession, cartItems } = this.state;
Matija Obreza's avatar
Matija Obreza committed
102
    const { t, appConfig: { apiUrl, shoppingCart, map }, appConfig } = this.props;
Matija Obreza's avatar
Matija Obreza committed
103
104
105
106
107

    let propertyIndex = 0;

    if (accession === null) {
      return (
Maksym Tishchenko's avatar
Maksym Tishchenko committed
108
109
110
111
        <>
          <PageTitle title={ t('loading') } />
          <Loading/>
        </>
Matija Obreza's avatar
Matija Obreza committed
112
113
114
      );
    } else {
      const details = accession.details;
Maksym Tishchenko's avatar
Maksym Tishchenko committed
115
      const pdci = accession.pdci;
Matija Obreza's avatar
Matija Obreza committed
116
117
      return (
        <>
Maksym Tishchenko's avatar
Maksym Tishchenko committed
118
          <PageTitle title={ t('pagetitle.accession', { accessionNumber: details.accessionNumber }) } />
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
          <div className="d-flex justify-content-between align-items-center">
            <h1>{ details.accessionNumber }</h1>
            { shoppingCart.enabled &&
              <div>
                { cartItems.includes(this.props.match.params.uuid) ?
                  <button
                    type="button"
                    name={ `button-remove-${accession.details.uuid}` }
                    data-uuid={ accession.details.uuid }
                    className="btn btn-primary"
                    onClick={ this.removeFromCart }
                  >
                    { t('cart.removeFromCart') }
                  </button>
                  :
                  this.renderAddToCart()
                }
              </div>
            }
          </div>

140
141
          { details.historic && <div className="bg-warning p-2 mb-2">{ t('accession.historicalNote') }</div> }

142
143
144
          { details.doi && <Property title={ t('accession.doi') } value={ <a href={ `https://doi.org/${details.doi}` } target="_blank">{ details.doi }</a> } index={ propertyIndex++ }/> }
          { details.accessionName && <Property title={ t('accession.accessionName') } value={ <b>{ details.accessionName }</b> } index={ propertyIndex++ }/> }
          <Property title={ t('accession.acceNumb') } value={ details.accessionNumber } index={ propertyIndex++ } />
Matija Obreza's avatar
Matija Obreza committed
145
          { details.institute && details.institute.fullName &&
Matija Obreza's avatar
Matija Obreza committed
146
            <Property title={ t('accession.holdingInstitute') } value={ details.institute.fullName } index={ propertyIndex++ }/>
Matija Obreza's avatar
Matija Obreza committed
147
148
          }
          { details.institute && details.institute.code &&
Matija Obreza's avatar
Matija Obreza committed
149
            <Property title={ t('accession.instituteCode') } value={ details.institute.code } index={ propertyIndex++ }/>
Matija Obreza's avatar
Matija Obreza committed
150
151
152
153
          }
          { details.institute && details.institute.owner &&
            <Property title="Data provider" value={ details.institute.owner.name } index={ propertyIndex++ }/>
          }
Matija Obreza's avatar
Matija Obreza committed
154
155
156
          { details.sampStat &&
            <Property title={ t('accession.sampStat') } value={ t(`accession.sampleStatus.${details.sampStat}`) } index={ propertyIndex++ }/>
          }
Matija Obreza's avatar
Matija Obreza committed
157
          { details.countryOfOrigin &&
Maksym Tishchenko's avatar
Maksym Tishchenko committed
158
159
160
            <Property title={ t('accession.countryOfOrigin') } value={
              <CountryName code3={ details.countryOfOrigin.code3 } /> || details.countryOfOrigin.name
            } index={ propertyIndex++ } />
Matija Obreza's avatar
Matija Obreza committed
161
162
163
164
          }
          { details.ancest &&
            <Property title="Ancestral information (pedigree)" value={ details.ancest } index={ propertyIndex++ }/>
          }
Maksym Tishchenko's avatar
Maksym Tishchenko committed
165
166
167
168
169
170
171
          { details.storage && details.storage.length > 0 &&
            <Property
              title={ t('accession.storageType') }
              titleStyle={ { display: 'flex', alignItems: 'center' } }
              value={  details.storage.map((storage, i) => <div key={ `${i}-${storage}` }>{t(`accession.storage.${storage}`)}</div>) }
              index={ propertyIndex++ } />
          }
Matija Obreza's avatar
Matija Obreza committed
172
173
174
175
176
177
178
179
180
          { details.aegis &&
            <Property title="AEGIS" value="Accession is part of the European Collection" index={ propertyIndex++ }/>
          }
          { (details.donorCode || details.donorName) &&
            <Property title="Donor institute" value={ <span>{ details.donorCode } { details.donorName }</span> } index={ propertyIndex++ }/>
          }
          { details.donorNumb &&
            <Property title="Donor accession number" value={ details.donorNumb } index={ propertyIndex++ }/>
          }
Maksym Tishchenko's avatar
Maksym Tishchenko committed
181
182
183
184
185
186
187
          { details.duplSite && details.duplSite.length > 0 &&
          <Property
            title={ t('accession.details.safetyDuplicationInstitute') }
            titleStyle={ { display: 'flex', alignItems: 'center' } }
            value={  details.duplSite.map((duplSite, i) => <div key={ `${i}-${duplSite}` }>{duplSite}</div>) }
            index={ propertyIndex++ } />
          }
Matija Obreza's avatar
Matija Obreza committed
188
          { details.acceUrl &&
189
            <Property title="Accession URL" value={ details.acceUrl } index={ propertyIndex++ }/>
Matija Obreza's avatar
Matija Obreza committed
190
          }
191
192
193
          {/* {details.crop && <Property title={ t('accession.crop') } value={ details.crop.shortName } index={ propertyIndex++ }/>} */}
          { details.cropName && <Property title={ t('accession.cropName') } value={ details.cropName } index={ propertyIndex++ }/> }

Maksym Tishchenko's avatar
Maksym Tishchenko committed
194
195
196
197
198
199
200
          { details.taxonomy &&
          <>
            <h3 className="mt-4">{t('accession.details.providedTaxonomy')}</h3>
            <Property title={ t('accession.taxonomy.genus') } value={ details.taxonomy.genus } index={ propertyIndex++ }/>
            <Property title={ t('accession.taxonomy.species') } value={ details.taxonomy.species } index={ propertyIndex++ }/>
            <Property title={ t('accession.taxonomy.scientificName') } value={ <span dangerouslySetInnerHTML={ { __html: details.taxonomy.taxonNameHtml } } /> } index={ propertyIndex++ }/>

201
202
203
204
            { details.taxonomy.grinTaxonomySpecies &&
              <Property title={ t('accession.taxonomy.grinTaxonName') } value={
                <a href={ `https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomydetail?id=${details.taxonomy.grinTaxonomySpecies.id}` }>
                  <GrinSpecies grinSpecies={ details.taxonomy.grinTaxonomySpecies } />
Maksym Tishchenko's avatar
Maksym Tishchenko committed
205
                </a>
206
207
208
209
210
211
212
213
              } index={ propertyIndex++ }/> }
            { details.taxonomy.currentTaxonomySpecies && details.taxonomy.currentTaxonomySpecies.id !== details.taxonomy.grinTaxonomySpecies.id &&
              <Property title={ t('accession.taxonomy.grinCurrentName') } value={
                <a href={ `https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomydetail?id=${details.taxonomy.currentTaxonomySpecies.id}` }>
                  <GrinSpecies grinSpecies={ details.taxonomy.currentTaxonomySpecies } />
                </a>
              } index={ propertyIndex++ }/> }
          </>
Maksym Tishchenko's avatar
Maksym Tishchenko committed
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
          }

          {details.aliases && details.aliases.length > 0 &&
          <>
            <h3 className="mt-4">{t('accession.details.accessionNames')}</h3>
            {
              details.aliases.map((alias) => (
                <Property key={ alias.id } title={ t(`accession.alias.${alias.aliasType}`) } value={ `${alias.name} ${alias.usedBy || ''}` } index={ propertyIndex++ }/>
              ))
            }
          </>
          }

          {
            details.remarks && details.remarks.length > 0 &&
            <>
              <h3 className="mt-4">{t('accession.details.remarks')}</h3>
              {
                details.remarks.map((remark) => (
                  <Property key={ remark.id } title={ remark.fieldName || remark.remark } value={ remark.fieldName ? remark.remark : '' } index={ propertyIndex++ }/>
                ))
              }
            </>
          }
Matija Obreza's avatar
Matija Obreza committed
238
239
240

          { details.coll &&
            <>
Maksym Tishchenko's avatar
Maksym Tishchenko committed
241
              <h3 className="mt-4">{t('accession.details.collSite')}</h3>
Matija Obreza's avatar
Matija Obreza committed
242
              <Property title={ t('accession.coll.collSite') } value={ details.coll.collSite } index={ propertyIndex++ }/>
243
244
245
              { details.coll.collSrc &&
                <Property title={ t('accession.coll.collSrc') } value={ t(`accession.collectingSource.${details.coll.collSrc}`) } index={ propertyIndex++ }/>
              }
Matija Obreza's avatar
Matija Obreza committed
246
247
248
249
              <Property title={ t('accession.coll.collDate') } value={ details.coll.collDate } index={ propertyIndex++ }/>
              <Property title={ t('accession.coll.collMissId') } value={ details.coll.collMissId } index={ propertyIndex++ }/>
              <Property title={ t('accession.coll.collCode') } value={ details.coll.collCode } index={ propertyIndex++ }/>
              <Property title={ t('accession.coll.collName') } value={ details.coll.collName } index={ propertyIndex++ }/>
Matija Obreza's avatar
Matija Obreza committed
250
251
252
253
            </>
          }
          { details.geo &&
            <>
Maksym Tishchenko's avatar
Maksym Tishchenko committed
254
              <h3 className="mt-4">{ t('accession.details.geo') }</h3>
Matija Obreza's avatar
Matija Obreza committed
255
256
257
258
259
              <Property title={ t('accession.geo.latitude') } value={ details.geo.latitude } index={ propertyIndex++ }/>
              <Property title={ t('accession.geo.longitude') } value={ details.geo.longitude } index={ propertyIndex++ }/>
              <Property title={ t('accession.geo.datum') } value={ details.geo.datum } index={ propertyIndex++ }/>
              <Property title={ t('accession.geo.uncertainty') } value={ details.geo.uncertainty } index={ propertyIndex++ }/>
              <Property title={ t('accession.geo.elevation') } value={ details.geo.elevation } index={ propertyIndex++ }/>
Oleksii Savran's avatar
Oleksii Savran committed
260
261
262
              { map.enabled && details.institute && details.geo.latitude && details.geo.longitude &&
                <LocationMap position={ { lat: details.geo.latitude, lng: details.geo.longitude } }/>
              }
Matija Obreza's avatar
Matija Obreza committed
263
264
265
266
267
            </>
          }

          { accession.imageGallery &&
            <>
Maksym Tishchenko's avatar
Maksym Tishchenko committed
268
              <h2 className="mt-4">{ t('accession.details.images') }</h2>
Matija Obreza's avatar
Matija Obreza committed
269
270
271
272
273
274
275
276
277
278
              <div>
                { accession.imageGallery.images.map((image, idx) => (
                  <span key={ idx }>
                    <a href={ `${apiUrl}/api/v1/repository/download/d${image.storagePath}` }><img className="img-thumbnail" src={ `${apiUrl}/api/v1/repository/download/d/_thumbs${image.thumbnailPath}/200x200.jpg` } alt={ image.subject } /></a>
                  </span>
                )) }
              </div>
            </>
          }

279
          { appConfig.accession.subsets && accession.subsets && accession.subsets.length > 0 &&
Matija Obreza's avatar
Matija Obreza committed
280
            <>
Matija Obreza's avatar
Matija Obreza committed
281
              <h2 className="mt-4">{ t('accession.subsets') }</h2>
Matija Obreza's avatar
Matija Obreza committed
282
283
              { accession.subsets.map((subset, idx) => (
                <div key={ idx }>
284
                  <Link to={`/subsets/${subset.uuid}` }>{ subset.title }</Link>
Matija Obreza's avatar
Matija Obreza committed
285
286
287
288
289
290
                  <p>{ subset.description }</p>
                </div>
              )) }
            </>
          }

291
          { appConfig.accession.datasets && accession.datasets && accession.datasets.length > 0 &&
Matija Obreza's avatar
Matija Obreza committed
292
            <>
Matija Obreza's avatar
Matija Obreza committed
293
              <h2 className="mt-4">{ t('accession.datasets') }</h2>
Matija Obreza's avatar
Matija Obreza committed
294
295
              { accession.datasets.map((dataset, idx) => (
                <div key={ idx }>
Matija Obreza's avatar
Matija Obreza committed
296
                  <Link to={`/datasets/${dataset.uuid}` }>{ dataset.title }</Link>
Matija Obreza's avatar
Matija Obreza committed
297
298
299
300
301
                  <p>{ dataset.description }</p>
                </div>
              )) }
            </>
          }
Maksym Tishchenko's avatar
Maksym Tishchenko committed
302

303
          { appConfig.accession.pdci && pdci && <PdciTable pdci={ pdci } title={ t('accession.details.pdci') }/> }
Maksym Tishchenko's avatar
Maksym Tishchenko committed
304
305
306
307
308
309
310
311
312

          <h2 className="mt-4">{ t('accession.details.metadata') }</h2>
          <Property title={ t('accession.details.uuid') } value={ `urn:uuid:${details.uuid}` } index={ propertyIndex++ }/>
          <Property title={ t('accession.details.permanentURL') } value={
            <a href={ `https://purl.org/germplasm/id/${details.uuid}` }>
              {`https://purl.org/germplasm/id/${details.uuid}`}
            </a> } index={ propertyIndex++ }/>
          {
            details.lastModifiedDate &&
313
            <Property title={ t('accession.details.lastUpdated') } value={ new Date(details.lastModifiedDate).toLocaleString() } index={ propertyIndex++ }/>
Maksym Tishchenko's avatar
Maksym Tishchenko committed
314
315
316
          }
          {
            details.createdDate &&
317
            <Property title={ t('accession.details.created') } value={ new Date(details.createdDate).toLocaleString() } index={ propertyIndex++ }/>
318
          }
Matija Obreza's avatar
Matija Obreza committed
319
320
321
        </>
      );
    }
Matija Obreza's avatar
Matija Obreza committed
322
  }
Matija Obreza's avatar
Matija Obreza committed
323
}
324

Oleksii Savran's avatar
Redux    
Oleksii Savran committed
325
const mapStateToProps = (state) => ({
326
  appConfig: state.appConfig.config,
Oleksii Savran's avatar
Oleksii Savran committed
327
  publicWebsiteUrl: (state.apiInfo.apiInfo && state.apiInfo.apiInfo.publicWebsiteUrl) || '',
Oleksii Savran's avatar
Redux    
Oleksii Savran committed
328
329
330
});

export default connect(mapStateToProps)(withTranslation()(AccessionDetailsPage));