DisplayPage.tsx 10.6 KB
Newer Older
Matija Obreza's avatar
Matija Obreza committed
1
2
3
4
import * as React from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';

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

7
import { loadDescriptor, publishDescriptor, deleteDescriptor } from 'actions/descriptors';
Matija Obreza's avatar
Matija Obreza committed
8

9
import { Descriptor, DataType as DescriptorDataType } from 'model/descriptor.model';
10
import { VocabularyTerm } from 'model/vocabulary.model';
Matija Obreza's avatar
Matija Obreza committed
11

12
13
import confirm from 'utilities/confirmAlert';
import Authorize from 'ui/common/authorized/Authorize';
14
import Loading from 'ui/common/Loading';
15
import Section from 'ui/common/layout/Section';
16
import Markdown from 'ui/catalog/markdown';
Matija Obreza's avatar
Matija Obreza committed
17
import ContentHeaderWithButton from 'ui/common/heading/ContentHeaderWithButton';
18
import PrettyDate from 'ui/common/time/PrettyDate';
19
import { ScrollToTopOnMount } from 'ui/common/page/scrollers';
20
import { PartnerLink, DescriptorLink, CropLink, DescriptorListLink, DatasetLink } from 'ui/catalog/Links';
21
import { Table, TableRow, TableCell } from 'ui/common/tables';
22
import { Properties, PropertiesItem } from 'ui/catalog/Properties';
23
import VocabularyCard from 'ui/pages/vocabulary/c/VocabularyCard';
24
import DescriptorScale from 'ui/catalog/descriptor/DescriptorScale';
Maxym Borodenko's avatar
Maxym Borodenko committed
25
import BackButton from 'ui/common/buttons/BackButton';
Matija Obreza's avatar
Matija Obreza committed
26
27

import Grid from 'material-ui/Grid';
28
import Card, { CardHeader, CardContent, CardActions } from 'ui/common/Card';
29
import Button from 'material-ui/Button';
30
import List, { ListItem, ListItemText } from 'material-ui/List';
Matija Obreza's avatar
Matija Obreza committed
31
32
33


interface IDisplayPageProps extends React.ClassAttributes<any> {
Matija Obreza's avatar
Matija Obreza committed
34
35
		classes: any;
		uuid?: string;
Matija Obreza's avatar
Matija Obreza committed
36

Matija Obreza's avatar
Matija Obreza committed
37
		loadDescriptor: (uuid: string) => void;
38
39
		publishDescriptor: (descriptor: Descriptor, published?: boolean) => void;
		deleteDescriptor: (descriptor: Descriptor) => void;
Matija Obreza's avatar
Matija Obreza committed
40
		descriptor: Descriptor;
41
		descriptorExtra: any;
Matija Obreza's avatar
Matija Obreza committed
42
43
44
45
}

class DisplayPage extends React.Component<IDisplayPageProps, any> {

Matija Obreza's avatar
Matija Obreza committed
46
47
48
49
50
51
52
53
54
55
56
57
		protected static needs = [
				({ params: { uuid } }) => loadDescriptor(uuid),
		];

		public componentDidMount() {
				const {descriptor, loadDescriptor, uuid} = this.props;

				if (uuid && (!descriptor || descriptor.uuid !== uuid)) {
						loadDescriptor(uuid);
				}
		}

58
		private onPublish = (e) => {
Matija Obreza's avatar
Matija Obreza committed
59
60
			const {descriptor, publishDescriptor} = this.props;

61
62
63
64
65
			confirm(<span>Publish <b>{ descriptor.title }</b>?</span>, {
					description: `After publishing the descriptor no changes are permitted, a new version must be created.`,
					confirmLabel: 'Publish',
					abortLabel: 'Cancel',
			}).then(() => {
Valeriy Panov's avatar
Valeriy Panov committed
66
					log('Publishing descriptor', descriptor);
67
68
69
70
					publishDescriptor(descriptor);
			}).catch(() => {
					// don't delete
			});
Matija Obreza's avatar
Matija Obreza committed
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
		private onUnpublish = (e) => {
      const {descriptor, publishDescriptor} = this.props;

      confirm(<span>Unpublish <b>{ descriptor.title }</b>?</span>, {
          // description: `Deleting the descriptor is only possible when there is no associated data.`,
          confirmLabel: 'Unpublish',
          abortLabel: 'Cancel',
      }).then(() => {
          publishDescriptor(descriptor, false);
      }).catch(() => {
          // don't delete
      });
    }

		private onDelete = (e) => {
      const {descriptor, deleteDescriptor} = this.props;

      confirm(<span>Delete <b>{ descriptor.title }</b>?</span>, {
          description: `Deleting the descriptor is only possible when there is no associated data.`,
          confirmLabel: 'Delete',
          abortLabel: 'Cancel',
      }).then(() => {
          deleteDescriptor(descriptor);
      }).catch(() => {
          // don't delete
      });
    }

Matija Obreza's avatar
Matija Obreza committed
101
		public render() {
102
				const {uuid, descriptor, descriptorExtra} = this.props;
Matija Obreza's avatar
Matija Obreza committed
103

104
				const stillLoading: boolean = (! descriptor || (uuid && (descriptor.uuid !== uuid)));
Matija Obreza's avatar
Matija Obreza committed
105

106
				// const terms: VocabularyTerm[] = descriptor ? (descriptor.terms || (descriptor.vocabulary ? descriptor.vocabulary.terms : null)) : null;
107
				// <PropertiesItem title="Publisher:">{ descriptor.publisher || <i>Not specified</i> }</PropertiesItem>
Matija Obreza's avatar
Matija Obreza committed
108
109
				return (
					<div>
110
						<ScrollToTopOnMount />
Maxym Borodenko's avatar
Maxym Borodenko committed
111
						<ContentHeaderWithButton title="Descriptor details" buttons={ <BackButton defaultTarget="/descriptors" /> } />
112
113
114
115
						{ stillLoading ? <Loading /> :
							<Grid container spacing={ 24 } className="p-20 back-gray">
								<Grid item xs={ 12 }>
									<Card square>
116
										<CardHeader title={ descriptor.title } />
117
										<CardContent>
118
											{ ! descriptor.published && <h2>This descriptor is not yet published!</h2> }
119
120
											{ descriptor.key && <h2>This descriptor is a key descriptor for access and utilization of PGR.</h2> }

121
											{ descriptor.description && <Markdown className="mb-20" source={ descriptor.description } /> }
122

123
124
125
126
											<Properties>
												{ descriptor.crop && <PropertiesItem title="Crop:"><CropLink code={ descriptor.crop } /></PropertiesItem> }
												<PropertiesItem title="Version:">{ descriptor.versionTag }</PropertiesItem>
												<PropertiesItem title="Category:">{ descriptor.category }</PropertiesItem>
Matija Obreza's avatar
Matija Obreza committed
127
128
												{ (descriptor.publisher === null && descriptor.owner) &&
													<PropertiesItem title="Maintained by:"><PartnerLink to={ descriptor.owner } /></PropertiesItem> }
129
											</Properties>
130
										</CardContent>
131
132
133
134
135
136
137
138
139
140
141
142
143
144

										{ (descriptor._permissions.write || descriptor._permissions.delete) && (
                      <CardActions>
												{ descriptor.published ?
													<Authorize role="ROLE_ADMINISTRATOR">
														<Button onClick={ this.onUnpublish } type="button">Un-publish</Button>
													</Authorize>
													:
													<Button onClick={ this.onPublish } type="button">Publish</Button>
												}
                        { ! descriptor.published && descriptor._permissions.write && <DescriptorLink edit to={ descriptor }><Button>Edit</Button></DescriptorLink> }
                        { ! descriptor.published && descriptor._permissions.delete && <Button onClick={ this.onDelete } type="button">Delete</Button> }
                      </CardActions>
                    ) }
145
146
147
148
									</Card>
								</Grid>

								<Grid item xs={ 12 }>
149
150
151
152
153
154
155
									<Section title="Descriptor definition" className="p-20">
										<Properties>
											<PropertiesItem title="Descriptor type:">{ descriptor.dataType }</PropertiesItem>
											{ descriptor.columnName && <PropertiesItem title="Database name:">{ descriptor.columnName }</PropertiesItem> }
											{ descriptor.minValue !== null && <PropertiesItem title="Minimum allowed value:">{ descriptor.minValue }</PropertiesItem> }
											{ descriptor.maxValue !== null && <PropertiesItem title="Maximum allowed value:">{ descriptor.maxValue }</PropertiesItem> }
										</Properties>
156
									</Section>
157
158
								</Grid>

159
160
161
162
163
164
								{ descriptor.dataType === DescriptorDataType.SCALE &&
									<Grid item xs={ 12 }>
										<Section title="Scale" className="p-20">
											<Properties>
												<PropertiesItem title="Allowed values:">{ descriptor.integerOnly ? 'Integers' : 'Decimals' }</PropertiesItem>
											</Properties>
165
											<DescriptorScale className="mt-20" decimal={ ! descriptor.integerOnly } min={ descriptor.minValue } max={ descriptor.maxValue } labels={ descriptor.terms } />
166
167
168
169
170
										</Section>
									</Grid>
								}

								{ descriptor.dataType === DescriptorDataType.CODED && descriptor.terms && descriptor.terms.length > 0 && (
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
									<Grid item xs={ 12 }>
										<Section title="Descriptor coding table">
											<Table widths={ [ '10%', '20%', null ] } headers={ (
													<TableRow>
														<TableCell>Code</TableCell>
														<TableCell>Term</TableCell>
														<TableCell>Description</TableCell>
													</TableRow>
												) }>
												{ descriptor.terms.map((term: VocabularyTerm) => (
													<TableRow key={ term.code }>
														<TableCell className="font-bold">{ term.code }</TableCell>
														<TableCell>{ term.title }</TableCell>
														<TableCell>{ term.description }</TableCell>
													</TableRow>
												)) }
											</Table>
										</Section>
									</Grid>
								) }

								{ descriptor.vocabulary && (
									<Grid item xs={ 12 }>
										<Section title="Controlled vocabulary">
											<div className="p-20">
196
197
198
												<p><b>Note:</b> This descriptor uses a controlled vocabulary { descriptor.vocabulary.publisher &&
													<span>published by <b>{ descriptor.vocabulary.publisher }</b></span>
												} maintained by <PartnerLink to={ descriptor.vocabulary.owner } />.</p>
199
200
201
202
											</div>
											<VocabularyCard vocabulary={ descriptor.vocabulary } />
										</Section>
									</Grid>
203
								) }
204

205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
								{ (descriptorExtra.datasets && descriptorExtra.datasets.length > 0) && (
									<Grid item xs={ 12 }>
										<Section title="Datasets">
											<List>
											{ descriptorExtra.datasets.map((dataset) => (
												<ListItem button key={ dataset.uuid }>
													<ListItemText primary={ <DatasetLink to={ dataset }><Markdown basic source={ dataset.title } /></DatasetLink> }
														secondary={ `${dataset.versionTag}` }
													/>
												</ListItem>
											)) }
											</List>
										</Section>
									</Grid>
								) }

								{ (descriptorExtra.descriptorLists && descriptorExtra.descriptorLists.length > 0) && (
									<Grid item xs={ 12 }>
										<Section title="Crop descriptors">
											<List>
											{ descriptorExtra.descriptorLists.map((descriptorList) => (
												<ListItem button key={ descriptorList.uuid }>
													<ListItemText primary={ <DescriptorListLink to={ descriptorList }><Markdown basic source={ descriptorList.title } /></DescriptorListLink> }
														secondary={ `${descriptorList.versionTag}` }
													/>
												</ListItem>
											)) }
											</List>
										</Section>
									</Grid>
								) }

237
238
239
240
241
								<Grid item xs={ 12 }>
									<Section title="Record metadata" className="p-20">
										<Properties>
											<PropertiesItem title="UUID:">{ descriptor.uuid }</PropertiesItem>
											<PropertiesItem title="Record version:">{ descriptor.version }</PropertiesItem>
242
											<PropertiesItem title="Last updated:"><PrettyDate value={ descriptor.lastModifiedDate } /></PropertiesItem>
243
244
245
										</Properties>
									</Section>
								</Grid>
246
247
							</Grid>
						}
Matija Obreza's avatar
Matija Obreza committed
248
249
250
					</div>
				);
		}
Matija Obreza's avatar
Matija Obreza committed
251
252
253
}

const mapStateToProps = (state, ownProps) => ({
Matija Obreza's avatar
Matija Obreza committed
254
255
	uuid: ownProps.params.uuid,
	descriptor: state.descriptors.currentDescriptor,
256
	descriptorExtra: state.descriptors.currentDescriptorExtra,
Matija Obreza's avatar
Matija Obreza committed
257
258
259
});

const mapDispatchToProps = (dispatch) => bindActionCreators({
Matija Obreza's avatar
Matija Obreza committed
260
261
	loadDescriptor,
	publishDescriptor,
262
	deleteDescriptor,
Matija Obreza's avatar
Matija Obreza committed
263
264
}, dispatch);

Maxim Babichev's avatar
Maxim Babichev committed
265
export default connect(mapStateToProps, mapDispatchToProps)(DisplayPage);