DatasetDisplay.tsx 14.9 KB
Newer Older
1
2
3
4

import * as React from 'react';
import { withStyles } from 'material-ui/styles';

Valeriy Panov's avatar
Valeriy Panov committed
5
6
import {log} from 'utilities/debug';

7
8
9
10
import { Dataset } from 'model/dataset.model';
import { Descriptor } from 'model/descriptor.model';
import { RepositoryFile } from 'model/repositoryFile.model';
import { Creator } from 'model/creator.model';
Valeriy Panov's avatar
Valeriy Panov committed
11
import { AVAILABLE_LICENSES } from 'model/license.model';
12
13
14
15

import confirm from 'utilities/confirmAlert';
import Authorize from 'ui/common/authorized/Authorize';
import Section from 'ui/common/layout/Section';
16
import Markdown from 'ui/catalog/markdown';
17
import PrettyDate from 'ui/common/time/PrettyDate';
18
import { DatasetLink, DescriptorLink } from 'ui/catalog/Links';
19
20
21
22

import Summary from './Summary';
import LocationMap from './LocationMap';
import Button from 'material-ui/Button';
Maxim Babichev's avatar
Maxim Babichev committed
23
import { Properties, PropertiesItem } from 'ui/catalog/Properties';
24
25
import Grid from 'material-ui/Grid';
import Divider from 'material-ui/Divider';
Matija Obreza's avatar
Matija Obreza committed
26
import List, { ListItem, ListItemText } from 'material-ui/List';
27

28
import AccessionIdentifiersTable from 'ui/catalog/accession/IdentifiersTable';
29

30
import Card, {CardHeader, CardContent, CardActions } from 'ui/common/Card';
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

const styles = (theme) => ({
    root: {
        flexGrow: 1,
    },
    gray: {
        backgroundColor: '#f3f2ee',
    },
    title: {
        fontSize: '30px',
        fontWeight: 'bold',
        [theme.breakpoints.down('md')]: {
            fontSize: '24px',
        },
    },
    grayRowsEven: theme.table.grayRowsEven,
    grayRowsOdd: theme.table.grayRowsOdd,
    green: {
        color: '#88ba42',
    },
    grayTitleBig: {
        fontSize: '14px',
        fontWeight: 'bold',
        lineHeight: '22px',
        padding: '15px 14px',
        margin: '0 1px',
        [theme.breakpoints.down('md')]: {
            marginLeft: '0',
            marginRight: '0',
        },
    },
    grayTitleSmall: {
        fontSize: '14px',
        lineHeight: '22px',
        padding: '10px 14px',
        margin: '0 1px',
        minHeight: '100%',
        [theme.breakpoints.down('md')]: {
            marginLeft: '0',
            marginRight: '0',
        },
    },
    rightTextWrapper: {
        display: 'flex',
        justifyContent: 'space-between',
        margin: '0 1px',
        padding: '10px 20px',
        [theme.breakpoints.down('md')]: {
            marginLeft: '0',
            marginRight: '0',
            padding: '10px 14px',
        },
    },
    buttonGreen: theme.buttons.green,
    dataContainer: {
        flexWrap: 'nowrap',
        marginBottom: '2px',
        wordWrap: 'break-word',
        [theme.breakpoints.down('md')]: {
            flexWrap: 'wrap',
        },
    },
    dataName: {
        [theme.breakpoints.down('lg')]: {
            display: 'none',
        },
    },
    margin1: {
        margin: '0 1px',
        [theme.breakpoints.down('md')]: {
            margin: '0',
        },
    },
    grayTitleA: {
        display: 'block',
        padding: '10px 14px',
    },
    centerAlign : {
         [theme.breakpoints.down('lg')]: {
            justifyContent: 'center',
         },
     },
    pdTop0: {
        [theme.breakpoints.down('md')]: {
            paddingTop: '0',
            marginLeft: '0',
            marginRight: '0',
        },
    },
});

interface IDetailInfoProps extends React.ClassAttributes<any> {
    classes: any;
    dataset: Dataset;
    publishDataset?: (dataset: Dataset, publish?: boolean) => any;
    deleteDataset?: (dataset: Dataset) => any;
}

class DetailInfo extends React.Component<IDetailInfoProps, any> {
    private onPublish = (e) => {
      const {dataset, publishDataset} = this.props;

      if (! publishDataset) {
        return;
      }

      confirm(<span>Publish <b>{ dataset.title }</b>?</span>, {
        description: `After publishing the dataset no changes are permitted, a new version must be created.`,
        confirmLabel: 'Publish',
        abortLabel: 'Cancel',
      }).then(() => {
Valeriy Panov's avatar
Valeriy Panov committed
142
        log('Publishing dataset', dataset);
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
        publishDataset(dataset);
      }).catch(() => {
          // don't
      });
    }

    private onUnpublish = (e) => {
      const {dataset, publishDataset} = this.props;

      if (! publishDataset) {
        return;
      }

      confirm(<span>Unpublish <b>{ dataset.title }</b>?</span>, {
          // description: `Deleting the descriptor is only possible when there is no associated data.`,
          confirmLabel: 'Unpublish',
          abortLabel: 'Cancel',
      }).then(() => {
Valeriy Panov's avatar
Valeriy Panov committed
161
        log('Publishing dataset', dataset);
162
163
164
165
166
167
168
169
170
171
172
173
174
175
        publishDataset(dataset, false);
      }).catch(() => {
          // don't
      });
    }

    private onDelete = (e) => {
      const {dataset, deleteDataset} = this.props;

      if (! deleteDataset) {
        return;
      }

      confirm(<span>Delete <b>{ dataset.title }</b>?</span>, {
Maxym Borodenko's avatar
Maxym Borodenko committed
176
          description: `Deleting the dataset will remove all related data.`,
177
178
179
180
181
182
183
184
185
186
187
188
189
          confirmLabel: 'Delete',
          abortLabel: 'Cancel',
      }).then(() => {
          deleteDataset(dataset);
      }).catch(() => {
          // don't
      });
    }

    public render() {
        const { classes, dataset, publishDataset, deleteDataset } = this.props;

        if (! dataset) {
Valeriy Panov's avatar
Valeriy Panov committed
190
          log('Waiting for dataset.');
191
192
193
          return null;
        }

Valeriy Panov's avatar
Valeriy Panov committed
194
195
        const license = dataset.rights && AVAILABLE_LICENSES.find((e) => e.code === dataset.rights);

196
197
198
        return (
            <div className={ classes.root }>
              <Grid container spacing={ 0 }>
Maxim Babichev's avatar
Maxim Babichev committed
199
                <Grid item xs={ 12 } className="p-10">
200
                    <Card className={ classes.card } square>
Matija Obreza's avatar
Matija Obreza committed
201
202
203
  										<CardHeader className={ classes.cardHeader }
                        title={ <Markdown basic source={ dataset.title } /> }
                        subheader={ <small>{ dataset.versionTag }</small> } />
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
  										<CardContent className={ classes.cardContent }>
                        { dataset.description && <Markdown source={ dataset.description } /> }
                      </CardContent>
                      { publishDataset && (dataset._permissions.write || dataset._permissions.delete) && (
                        <CardActions>
                          { dataset.published ?
                            <Authorize role="ROLE_ADMINISTRATOR">
                              <Button onClick={ this.onUnpublish } type="button">Un-publish</Button>
                            </Authorize>
                            :
                            <Button onClick={ this.onPublish } type="button">Publish</Button>
                          }
                          { ! dataset.published && dataset._permissions.write && <DatasetLink edit to={ dataset }><Button>Edit</Button></DatasetLink> }
                          { ! dataset.published && deleteDataset && dataset._permissions.delete && <Button onClick={ this.onDelete } type="button">Delete</Button> }
                        </CardActions>
                      ) }
                  </Card>
                </Grid>
              </Grid>

              <Grid container spacing={ 0 }>
Maxim Babichev's avatar
Maxim Babichev committed
225
                <Grid item xs={ 12 } md={ 8 } lg={ 9 } className="p-10">
226
                  <Section title="Dataset metadata">
Matija Obreza's avatar
Matija Obreza committed
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
                    { dataset.creators && dataset.creators.length > 0 &&
                      <div>
                        <div className="pt-15 pb-15 pl-20 pr-20">
                            <h4 className="font-bold m-0">Creators</h4>
                        </div>
                        <Divider/>
                        <Grid container spacing={ 0 } className="p-20">
                            <Grid item xs={ 12 }>
                              <Properties>
                                { dataset.creators && dataset.creators.map((e: Creator, i) => (
                                  <PropertiesItem title={ e.role } key={ e.id }>
                                      <p><b>{ e.fullName }</b></p>
                                      { e.institutionalAffiliation && <p>{ e.institutionalAffiliation }</p> }
                                      { e.email && <div><a href={ `mailto:${e.email}` }>{ e.email }</a></div> }
                                  </PropertiesItem>
                                )) }
                              </Properties>
                            </Grid>
                        </Grid>
                        <Divider/>
247
                      </div>
Matija Obreza's avatar
Matija Obreza committed
248
249
                    }

Matija Obreza's avatar
Matija Obreza committed
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
                      <div className="pt-15 pb-15 pl-20 pr-20">
                          <h4 className="font-bold m-0">Dataset use and licensing</h4>
                      </div>
                      <Divider/>
                      { license &&
                        <Grid container spacing={ 0 } className="p-20">
                            <Properties>
                                <PropertiesItem title="Licensed under:"><b>{ license.code }</b> { license.title }</PropertiesItem>
                                { license.url &&
                                  <PropertiesItem title="More information:">
                                    <a href={ license.url } target="_blank">{ license.url }</a>
                                  </PropertiesItem>
                                }
                            </Properties>
                        </Grid>
                      }
Matija Obreza's avatar
Matija Obreza committed
266

Matija Obreza's avatar
Matija Obreza committed
267
                      <Divider/>
Maxim Babichev's avatar
Maxim Babichev committed
268
269
                      <div className="pt-15 pb-15 pl-20 pr-20">
                          <h4 className="font-bold m-0">
Matija Obreza's avatar
Matija Obreza committed
270
                              Data and resources
Maxim Babichev's avatar
Maxim Babichev committed
271
                          </h4>
272
273
274
275
                      </div>
                      <Divider/>
                      <Grid container spacing={ 0 } className="p-20">
                          <Grid item xs={ 12 }>
Matija Obreza's avatar
Matija Obreza committed
276
                            <Properties>
277
                              {
Matija Obreza's avatar
Matija Obreza committed
278
279
280
281
282
283
284
285
286
287
288
                                  dataset.repositoryFiles && dataset.repositoryFiles.map((e: RepositoryFile) => (
                                      <PropertiesItem key={ e.uuid } title={
                                        <a href={ `/proxy/api/v0/repository/download/${e.uuid}` }>
                                          <Button raised component="span" className={ `${classes.buttonGreen} ${classes.button}` }>
                                            Download
                                          </Button>
                                        </a>
                                       }>
                                          <p>{ e.title || 'Dataset file' }</p>
                                          <p>{ e.originalFilename }</p>
                                      </PropertiesItem>
289
290
                                  ))
                              }
Matija Obreza's avatar
Matija Obreza committed
291
                            </Properties>
292
293
294
                          </Grid>
                      </Grid>
                      <Divider/>
Maxim Babichev's avatar
Maxim Babichev committed
295
296
                      <div className="pt-15 pb-15 pl-20 pr-20">
                          <h4 className="font-bold m-0">
297
                              Dates
Maxim Babichev's avatar
Maxim Babichev committed
298
                          </h4>
299
300
301
302
                      </div>
                      <Divider/>
                      <Grid container spacing={ 0 } className="p-20">
                          <Grid item xs={ 12 }>
Maxim Babichev's avatar
Maxim Babichev committed
303
304
                              <Grid container spacing={ 0 }>
                                  <Properties>
Matija Obreza's avatar
Matija Obreza committed
305
                                          <PropertiesItem title="Metadata create date:">
Maxim Babichev's avatar
Maxim Babichev committed
306
307
                                              { dataset.createdDate && <PrettyDate value={ dataset.createdDate } /> }
                                          </PropertiesItem>
Matija Obreza's avatar
Matija Obreza committed
308
                                          <PropertiesItem title="Metadata updated date:">
Maxim Babichev's avatar
Maxim Babichev committed
309
310
311
                                              { dataset.lastModifiedDate && <PrettyDate value={ dataset.lastModifiedDate } /> }
                                          </PropertiesItem>
                                  </Properties>
312
313
314
315
                              </Grid>
                          </Grid>
                      </Grid>
                      <Divider/>
Maxim Babichev's avatar
Maxim Babichev committed
316
317
                      <div className="pt-15 pb-15 pl-20 pr-20">
                          <h4 className="font-bold m-0">
318
                              Other Metadata
Maxim Babichev's avatar
Maxim Babichev committed
319
                          </h4>
320
321
322
323
                      </div>
                      <Divider/>
                      <Grid container spacing={ 0 } className="p-20">
                          <Grid item xs={ 12 }>
Maxim Babichev's avatar
Maxim Babichev committed
324
325
                              <Grid container spacing={ 0 }>
                                  <Properties>
Matija Obreza's avatar
Matija Obreza committed
326
                                      <PropertiesItem title="Date of dataset:">{ dataset.created }</PropertiesItem>
Maxim Babichev's avatar
Maxim Babichev committed
327
                                      <PropertiesItem title="Related resources:">{ dataset.source }</PropertiesItem>
Matija Obreza's avatar
Matija Obreza committed
328
                                      <PropertiesItem title="Resolve type:">Dataset</PropertiesItem>
Maxim Babichev's avatar
Maxim Babichev committed
329
                                  </Properties>
330
331
332
333
334
335
                              </Grid>
                          </Grid>
                      </Grid>
                  </Section>
                </Grid>

Maxim Babichev's avatar
Maxim Babichev committed
336
                <Grid item xs={ 12 } md={ 4 } lg={ 3 } className="p-10">
337
338
339
340
341
                  <Summary dataset={ dataset } creators={ dataset.creators } owner={ dataset.owner } classes={ {} } />
                </Grid>
              </Grid>

              <Grid container spacing={ 0 }>
342
343
                  { dataset.locations && dataset.locations.length > 0 && (
                      <Grid item xs={ 12 } md={ 12 } lg={ 12 } className="p-10">
Valeriy Panov's avatar
Valeriy Panov committed
344
345
346
347
348
349
350
351
                          <Section title="Locations">
                              <div className="p-20">
                                  <LocationMap locations={ dataset.locations } classes={ {} }/>
                              </div>
                          </Section>
                      </Grid>
                  ) }

Matija Obreza's avatar
Matija Obreza committed
352
                  { dataset.descriptors && dataset.descriptors.length > 0 && (
Maxim Babichev's avatar
Maxim Babichev committed
353
                    <Grid item xs={ 12 } md={ 12 } lg={ 12 } className="p-10">
354
                      <Section title="Traits observed">
Matija Obreza's avatar
Matija Obreza committed
355
                        <List>
356
                        { dataset.descriptors.map((descriptor: Descriptor) => (
Matija Obreza's avatar
Matija Obreza committed
357
358
359
360
                          <ListItem key={ descriptor.uuid } className="">
                            <ListItemText primary={ <DescriptorLink to={ descriptor } /> }
                              secondary={ descriptor.description && <Markdown source={ descriptor.description } /> } />
                          </ListItem>
361
                        )) }
Matija Obreza's avatar
Matija Obreza committed
362
                        </List>
363
364
365
366
                      </Section>
                    </Grid>
                  ) }

Matija Obreza's avatar
Matija Obreza committed
367
                  { dataset.accessionIdentifiers && dataset.accessionIdentifiers.length > 0 && (
Maxim Babichev's avatar
Maxim Babichev committed
368
                    <Grid item xs={ 12 } md={ 12 } lg={ 12 } className="p-10">
369
370
                      <Section title="Accessions evaluated">
                          <div className="p-20">
371
                              <AccessionIdentifiersTable accessionIdentifiers={ dataset.accessionIdentifiers } />
372
373
374
375
376
377
378
379
380
381
382
383
                          </div>
                      </Section>
                    </Grid>
                  ) }
              </Grid>
            </div>
        );
    }

}

export default ((withStyles as any)(styles)(DetailInfo));